@pisell/pisellos 2.2.11 → 2.2.12

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 (37) hide show
  1. package/dist/modules/Cart/utils/cartProduct.js +41 -26
  2. package/dist/modules/Discount/index.d.ts +2 -0
  3. package/dist/modules/Discount/index.js +69 -36
  4. package/dist/modules/Discount/types.d.ts +16 -0
  5. package/dist/modules/Order/index.js +4 -1
  6. package/dist/modules/Order/utils.d.ts +1 -0
  7. package/dist/modules/Order/utils.js +9 -0
  8. package/dist/modules/Rules/index.d.ts +7 -0
  9. package/dist/modules/Rules/index.js +1032 -195
  10. package/dist/modules/Rules/types.d.ts +4 -1
  11. package/dist/solution/BookingByStep/index.d.ts +1 -1
  12. package/dist/solution/BookingByStep/index.js +1 -0
  13. package/dist/solution/BookingTicket/index.d.ts +1 -1
  14. package/dist/solution/ShopDiscount/index.d.ts +2 -0
  15. package/dist/solution/ShopDiscount/index.js +80 -19
  16. package/dist/solution/ShopDiscount/types.d.ts +4 -1
  17. package/dist/solution/ShopDiscount/utils.d.ts +55 -0
  18. package/dist/solution/ShopDiscount/utils.js +432 -3
  19. package/lib/modules/Cart/utils/cartProduct.js +35 -22
  20. package/lib/modules/Discount/index.d.ts +2 -0
  21. package/lib/modules/Discount/index.js +19 -4
  22. package/lib/modules/Discount/types.d.ts +16 -0
  23. package/lib/modules/Order/index.js +2 -0
  24. package/lib/modules/Order/utils.d.ts +1 -0
  25. package/lib/modules/Order/utils.js +11 -0
  26. package/lib/modules/Rules/index.d.ts +7 -0
  27. package/lib/modules/Rules/index.js +809 -177
  28. package/lib/modules/Rules/types.d.ts +4 -1
  29. package/lib/solution/BookingByStep/index.d.ts +1 -1
  30. package/lib/solution/BookingByStep/index.js +4 -0
  31. package/lib/solution/BookingTicket/index.d.ts +1 -1
  32. package/lib/solution/ShopDiscount/index.d.ts +2 -0
  33. package/lib/solution/ShopDiscount/index.js +55 -9
  34. package/lib/solution/ShopDiscount/types.d.ts +4 -1
  35. package/lib/solution/ShopDiscount/utils.d.ts +55 -0
  36. package/lib/solution/ShopDiscount/utils.js +266 -3
  37. package/package.json +1 -1
@@ -36,8 +36,7 @@ var import_BaseModule = require("../BaseModule");
36
36
  var import_utils = require("../../solution/ShopDiscount/utils");
37
37
  var import_utils2 = require("../Cart/utils");
38
38
  var import_decimal = __toESM(require("decimal.js"));
39
- var import_lodash_es = require("lodash-es");
40
- var flatItem;
39
+ var import_dayjs = __toESM(require("dayjs"));
41
40
  var RulesModule = class extends import_BaseModule.BaseModule {
42
41
  constructor(name, version) {
43
42
  super(name, version);
@@ -108,9 +107,13 @@ var RulesModule = class extends import_BaseModule.BaseModule {
108
107
  let hasApplicableDiscount = false;
109
108
  const newDiscountIds = newDiscountList.map((discount) => discount.id);
110
109
  result.productList.forEach((product) => {
111
- const { discount_list } = this.hooks.getProduct(product);
112
- if (discount_list && discount_list.length > 0) {
113
- const usedNewDiscount = discount_list.some(
110
+ const { discount_list, bundle } = this.hooks.getProduct(product);
111
+ const allDiscountList = [...discount_list || []];
112
+ (bundle || []).forEach((item) => {
113
+ allDiscountList.push(...(item == null ? void 0 : item.discount_list) || []);
114
+ });
115
+ if (allDiscountList && allDiscountList.length > 0) {
116
+ const usedNewDiscount = allDiscountList.some(
114
117
  (discount) => {
115
118
  var _a;
116
119
  return newDiscountIds.includes((_a = discount == null ? void 0 : discount.discount) == null ? void 0 : _a.resource_id);
@@ -145,6 +148,49 @@ var RulesModule = class extends import_BaseModule.BaseModule {
145
148
  const filteredDiscountList = addModeDiscount.filter((discount) => {
146
149
  return !discount.isManualSelect;
147
150
  });
151
+ const flattenProductsWithBundle = (productList2) => {
152
+ const flattened = [];
153
+ productList2.forEach((originProduct) => {
154
+ const product = this.hooks.getProduct(originProduct);
155
+ flattened.push({
156
+ type: "main",
157
+ originProduct,
158
+ product,
159
+ price: Number(product.price || 0),
160
+ id: product.id,
161
+ _id: product._id,
162
+ parentId: product._id,
163
+ quantity: product.quantity,
164
+ num: product.num
165
+ });
166
+ if (product.bundle && Array.isArray(product.bundle) && product.bundle.length > 0) {
167
+ product.bundle.forEach((bundleItem, bundleIndex) => {
168
+ flattened.push({
169
+ type: "bundle",
170
+ originProduct,
171
+ parentProduct: product,
172
+ bundleItem,
173
+ bundleIndex,
174
+ // 虚拟商品属性
175
+ price: Number(bundleItem.price || 0),
176
+ id: bundleItem._bundle_product_id,
177
+ // 🔥 使用 _bundle_product_id
178
+ _id: `${product._id}_bundle_${bundleIndex}`,
179
+ parentId: product._id,
180
+ num: bundleItem.num || 1,
181
+ quantity: bundleItem.num || 1,
182
+ total: new import_decimal.default(bundleItem.price || 0).mul(bundleItem.num || 1).toNumber(),
183
+ origin_total: new import_decimal.default(bundleItem.price || 0).mul(bundleItem.num || 1).toNumber(),
184
+ original_price: bundleItem.original_price,
185
+ // 继承主商品属性
186
+ booking_id: product.booking_id,
187
+ discount_list: bundleItem.discount_list || []
188
+ });
189
+ });
190
+ }
191
+ });
192
+ return flattened;
193
+ };
148
194
  const sortedDiscountList = [...filteredDiscountList].sort((a, b) => {
149
195
  var _a, _b;
150
196
  if (a.tag === "good_pass" && b.tag !== "good_pass")
@@ -171,7 +217,7 @@ var RulesModule = class extends import_BaseModule.BaseModule {
171
217
  if (a.par_value !== b.par_value) {
172
218
  const valueA = new import_decimal.default(100).minus(a.par_value || 0);
173
219
  const valueB = new import_decimal.default(100).minus(b.par_value || 0);
174
- return valueB.minus(valueA).toNumber();
220
+ return valueA.minus(valueB).toNumber();
175
221
  }
176
222
  }
177
223
  return compareByExpireTime(a, b);
@@ -186,19 +232,26 @@ var RulesModule = class extends import_BaseModule.BaseModule {
186
232
  return itemA.expire_time ? -1 : itemB.expire_time ? 1 : 0;
187
233
  }
188
234
  });
189
- const sortedProductList = [...productList].sort((a, b) => {
235
+ const flattenedList = flattenProductsWithBundle(productList);
236
+ const sortedFlattenedList = flattenedList.sort((a, b) => {
190
237
  var _a, _b;
191
- const aProduct = this.hooks.getProduct(a);
192
- const bProduct = this.hooks.getProduct(b);
193
- const priceA = new import_decimal.default(aProduct.price || "0");
194
- const priceB = new import_decimal.default(bProduct.price || "0");
195
- if (priceA.toNumber() === priceB.toNumber()) {
196
- if (aProduct.quantity === bProduct.quantity) {
197
- return ((_a = bProduct.discount_list) == null ? void 0 : _a.length) - ((_b = aProduct.discount_list) == null ? void 0 : _b.length);
238
+ const priceA = new import_decimal.default(a.price || "0");
239
+ const priceB = new import_decimal.default(b.price || "0");
240
+ if (priceA.equals(priceB)) {
241
+ if (a.type !== b.type) {
242
+ return a.type === "main" ? -1 : 1;
243
+ }
244
+ if (a.type === "main" && b.type === "main") {
245
+ if (a.product.quantity === b.product.quantity) {
246
+ return (((_a = b.product.discount_list) == null ? void 0 : _a.length) || 0) - (((_b = a.product.discount_list) == null ? void 0 : _b.length) || 0);
247
+ }
248
+ return a.product.quantity - b.product.quantity;
249
+ }
250
+ if (a.type === "bundle" && b.type === "bundle") {
251
+ return (a.num || 1) - (b.num || 1);
198
252
  }
199
- return aProduct.quantity - bProduct.quantity;
200
253
  }
201
- return priceB.toNumber() - priceA.toNumber();
254
+ return priceB.minus(priceA).toNumber();
202
255
  });
203
256
  const usedDiscounts = /* @__PURE__ */ new Map();
204
257
  const discountApplicability = /* @__PURE__ */ new Map();
@@ -209,10 +262,27 @@ var RulesModule = class extends import_BaseModule.BaseModule {
209
262
  });
210
263
  const processedProductsMap = /* @__PURE__ */ new Map();
211
264
  const appliedDiscountProducts = /* @__PURE__ */ new Map();
212
- sortedProductList.forEach((originProduct) => {
213
- const product = this.hooks.getProduct(originProduct);
265
+ sortedFlattenedList.forEach((flatItem) => {
266
+ let product, originProduct;
267
+ if (flatItem.type === "main") {
268
+ product = flatItem.product;
269
+ originProduct = flatItem.originProduct;
270
+ } else {
271
+ product = {
272
+ _id: flatItem._id,
273
+ id: flatItem.id,
274
+ price: flatItem.price,
275
+ quantity: flatItem.quantity,
276
+ num: flatItem.num,
277
+ total: flatItem.total,
278
+ origin_total: flatItem.origin_total,
279
+ booking_id: flatItem.booking_id,
280
+ discount_list: flatItem.discount_list || []
281
+ };
282
+ originProduct = flatItem.originProduct;
283
+ }
214
284
  addModeDiscount.forEach((discount) => {
215
- var _a, _b, _c, _d, _e, _f;
285
+ var _a, _b, _c, _d, _e, _f, _g, _h;
216
286
  const limitedData = discount == null ? void 0 : discount.limited_relation_product_data;
217
287
  const isHolderMatch = this.checkHolderMatch(
218
288
  discount,
@@ -221,47 +291,80 @@ var RulesModule = class extends import_BaseModule.BaseModule {
221
291
  },
222
292
  holders
223
293
  );
294
+ let timeLimit = true;
295
+ timeLimit = !!(0, import_utils.filterDiscountListByBookingTime)([discount], ((product == null ? void 0 : product.startDate) || (0, import_dayjs.default)()).format("YYYY-MM-DD HH:mm:ss")).length;
224
296
  const isLimitedProduct = (limitedData.type === "product_all" || limitedData.product_ids && limitedData.product_ids.includes(product.id)) && isHolderMatch;
225
- const isAvailableProduct = !((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((discount2) => discount2.id && ["good_pass", "discount_card", "product_discount_card"].includes(discount2.tag || discount2.type))));
226
- if (isAvailableProduct && isLimitedProduct) {
227
- (_e = discountApplicability.get(discount.id)) == null ? void 0 : _e.push(product.id);
297
+ 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((discount2) => discount2.id && ["good_pass", "discount_card", "product_discount_card"].includes(discount2.tag || discount2.type)))) : !((flatItem == null ? void 0 : flatItem.booking_id) && ((_f = (_e = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _e.metadata) == null ? void 0 : _f.custom_product_bundle_map_id));
298
+ const isBundleAvailable = this.checkPackageSubItemUsageRules(discount, flatItem);
299
+ if (isAvailableProduct && isLimitedProduct && isBundleAvailable && timeLimit) {
300
+ (_g = discountApplicability.get(discount.id)) == null ? void 0 : _g.push(product.id);
228
301
  const applicableProducts = discountApplicableProducts.get(discount.id) || [];
229
302
  const discountType = discount.tag || discount.type;
303
+ const isGoodPass = discountType === "good_pass";
304
+ const num = isGoodPass || (flatItem == null ? void 0 : flatItem.type) === "main" ? 1 : product.num;
230
305
  const productData = {
231
- amount: product.price,
306
+ amount: product.price * num,
232
307
  type: discountType,
233
308
  tag: discountType,
234
309
  discount: {
235
- discount_card_type: (_f = discount == null ? void 0 : discount.metadata) == null ? void 0 : _f.discount_card_type,
310
+ discount_card_type: (_h = discount == null ? void 0 : discount.metadata) == null ? void 0 : _h.discount_card_type,
236
311
  fixed_amount: product.price,
237
312
  resource_id: discount.id,
238
313
  title: discount.format_title,
239
- original_amount: product.origin_total,
314
+ original_amount: product.price || product.origin_total,
240
315
  pre_value: discount.par_value,
241
316
  product_id: originProduct.id
317
+ },
318
+ metadata: {
319
+ num
242
320
  }
243
321
  };
244
- if (discountType !== "good_pass") {
245
- productData.num = product.num || 1;
246
- }
247
322
  applicableProducts.push(productData);
248
323
  discountApplicableProducts.set(discount.id, applicableProducts);
249
324
  }
250
325
  });
251
326
  });
252
- console.log(sortedProductList, "sortedProductListsortedProductList");
253
- sortedProductList.forEach((originProduct, index) => {
254
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
255
- const product = this.hooks.getProduct(originProduct);
256
- if ((product == null ? void 0 : product.booking_id) && ((_a = product.discount_list) == null ? void 0 : _a.length) && ((_b = product == null ? void 0 : product.discount_list) == null ? void 0 : _b.every((discount) => discount.id && ["good_pass", "discount_card", "product_discount_card"].includes(discount.tag || discount.type)))) {
257
- processedProductsMap.set(product._id, [originProduct]);
327
+ const processedFlatItemsMap = /* @__PURE__ */ new Map();
328
+ sortedFlattenedList.forEach((flatItem, index) => {
329
+ 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;
330
+ let product, originProduct;
331
+ if (flatItem.type === "main") {
332
+ product = flatItem.product;
333
+ originProduct = flatItem.originProduct;
334
+ } else {
335
+ product = {
336
+ _id: flatItem._id,
337
+ id: flatItem.id,
338
+ price: flatItem.price,
339
+ quantity: flatItem.quantity,
340
+ num: flatItem.num,
341
+ total: flatItem.total,
342
+ original_price: (_a = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _a.original_price,
343
+ origin_total: (_b = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _b.original_price,
344
+ booking_id: flatItem.booking_id,
345
+ discount_list: ((_c = flatItem == null ? void 0 : flatItem.bundleItem) == null ? void 0 : _c.discount_list) || []
346
+ };
347
+ originProduct = flatItem.originProduct;
348
+ }
349
+ if ((product == null ? void 0 : product.booking_id) && ((_d = product.discount_list) == null ? void 0 : _d.length) && ((_e = product == null ? void 0 : product.discount_list) == null ? void 0 : _e.every((discount) => discount.id && ["good_pass", "discount_card", "product_discount_card"].includes(discount.tag || discount.type)))) {
350
+ if (flatItem.type === "main") {
351
+ processedProductsMap.set(product._id, [originProduct]);
352
+ } else {
353
+ processedFlatItemsMap.set(flatItem._id, [{
354
+ ...flatItem,
355
+ processed: true
356
+ }]);
357
+ }
258
358
  return;
259
359
  }
260
360
  const applicableDiscounts = sortedDiscountList.filter((discount) => {
261
- var _a2, _b2, _c2;
262
- if ((Number(product.price) <= 0 || !product.price) && (discount.tag || discount.type) === "good_pass")
361
+ var _a2, _b2, _c2, _d2;
362
+ if ((Number(product.price) <= 0 || !product.price) && !((_a2 = product.discount_list) == null ? void 0 : _a2.find((n) => {
363
+ var _a3;
364
+ return ((_a3 = n.discount) == null ? void 0 : _a3.resource_id) === discount.id;
365
+ })) && (discount.tag || discount.type) === "good_pass")
263
366
  return false;
264
- if ((Number(product.total) <= 0 || !product.total) && !((_a2 = product.discount_list) == null ? void 0 : _a2.find((n) => {
367
+ if ((Number(product.price) === 0 || !product.price) && !((_b2 = product.discount_list) == null ? void 0 : _b2.find((n) => {
265
368
  var _a3;
266
369
  return ((_a3 = n.discount) == null ? void 0 : _a3.resource_id) === discount.id;
267
370
  })) && (discount.tag || discount.type) !== "good_pass")
@@ -270,32 +373,98 @@ var RulesModule = class extends import_BaseModule.BaseModule {
270
373
  if (targetUsedDiscounts && (discount.tag || discount.type) === "good_pass")
271
374
  return false;
272
375
  const limitedData = discount.limited_relation_product_data;
376
+ let timeLimit = true;
377
+ timeLimit = !!(0, import_utils.filterDiscountListByBookingTime)([discount], (product.startDate || (0, import_dayjs.default)()).format("YYYY-MM-DD HH:mm:ss")).length;
378
+ if (!timeLimit) {
379
+ return false;
380
+ }
273
381
  const isHolderMatch = this.checkHolderMatch(
274
382
  discount,
275
383
  {
276
- holder_id: ((flatItem == null ? void 0 : flatItem.type) === "bundle" ? (_b2 = flatItem == null ? void 0 : flatItem.parentProduct) == null ? void 0 : _b2.holder_id : (_c2 = flatItem == null ? void 0 : flatItem.product) == null ? void 0 : _c2.holder_id) || product.holder_id
384
+ holder_id: ((flatItem == null ? void 0 : flatItem.type) === "bundle" ? (_c2 = flatItem == null ? void 0 : flatItem.parentProduct) == null ? void 0 : _c2.holder_id : (_d2 = flatItem == null ? void 0 : flatItem.product) == null ? void 0 : _d2.holder_id) || product.holder_id
277
385
  },
278
386
  holders
279
387
  );
280
388
  if (!isHolderMatch)
281
389
  return false;
282
390
  if (limitedData.type === "product_all") {
391
+ if (!this.checkPackageSubItemUsageRules(discount, flatItem)) {
392
+ return false;
393
+ }
283
394
  return true;
284
395
  } else if (limitedData.product_ids && limitedData.product_ids.includes(product.id)) {
396
+ if (!this.checkPackageSubItemUsageRules(discount, flatItem)) {
397
+ return false;
398
+ }
285
399
  return true;
286
400
  }
287
401
  return false;
288
402
  });
289
403
  const selectedDiscountCard = applicableDiscounts.find((n) => n.isScan && n.isSelected && (n.tag || n.type) !== "good_pass");
290
404
  const selectedDiscount = selectedDiscountCard || applicableDiscounts[0];
291
- let isManualDiscount = typeof product.isManualDiscount === "boolean" ? product.isManualDiscount : product.total != product.origin_total && (!((_c = product.discount_list) == null ? void 0 : _c.length) || ((_e = (_d = product == null ? void 0 : product.discount_list) == null ? void 0 : _d.every) == null ? void 0 : _e.call(_d, (item) => item.type === "product")));
292
- if ((options == null ? void 0 : options.discountId) && ((_f = product.discount_list) == null ? void 0 : _f.some((item) => {
293
- var _a2;
294
- return ((_a2 = item.discount) == null ? void 0 : _a2.resource_id) === options.discountId;
295
- }))) {
296
- isManualDiscount = false;
405
+ let isManualDiscount = false;
406
+ if (flatItem.type === "main") {
407
+ isManualDiscount = typeof product.isManualDiscount === "boolean" ? product.isManualDiscount : product.total != product.origin_total && (product.bundle || []).every((item) => {
408
+ var _a2;
409
+ return !((_a2 = item.discount_list || []) == null ? void 0 : _a2.length);
410
+ }) && (!((_f = product.discount_list) == null ? void 0 : _f.length) || ((_h = (_g = product == null ? void 0 : product.discount_list) == null ? void 0 : _g.every) == null ? void 0 : _h.call(_g, (item) => item.type === "product")));
411
+ } else {
412
+ const parentProduct = flatItem.parentProduct;
413
+ if (parentProduct) {
414
+ isManualDiscount = typeof parentProduct.isManualDiscount === "boolean" ? parentProduct.isManualDiscount : parentProduct.total != parentProduct.origin_total && (parentProduct.bundle || []).every((item) => {
415
+ var _a2;
416
+ return !((_a2 = item.discount_list || []) == null ? void 0 : _a2.length);
417
+ }) && (!((_i = parentProduct.discount_list) == null ? void 0 : _i.length) || ((_k = (_j = parentProduct == null ? void 0 : parentProduct.discount_list) == null ? void 0 : _j.every) == null ? void 0 : _k.call(_j, (item) => item.type === "product")));
418
+ }
297
419
  }
298
- if ((options == null ? void 0 : options.selectedList) && ((_g = product.discount_list) == null ? void 0 : _g.some((item) => {
420
+ if (options == null ? void 0 : options.discountId) {
421
+ if (flatItem.type === "main" && ((_l = product.discount_list) == null ? void 0 : _l.some((item) => {
422
+ var _a2;
423
+ return ((_a2 = item.discount) == null ? void 0 : _a2.resource_id) === options.discountId;
424
+ }))) {
425
+ isManualDiscount = false;
426
+ }
427
+ if (flatItem.type === "bundle") {
428
+ if (((_m = product.discount_list) == null ? void 0 : _m.some((item) => {
429
+ var _a2;
430
+ return ((_a2 = item.discount) == null ? void 0 : _a2.resource_id) === options.discountId;
431
+ })) || ((_o = (_n = flatItem.parentProduct) == null ? void 0 : _n.discount_list) == null ? void 0 : _o.some((item) => {
432
+ var _a2;
433
+ return ((_a2 = item.discount) == null ? void 0 : _a2.resource_id) === options.discountId;
434
+ }))) {
435
+ isManualDiscount = false;
436
+ }
437
+ }
438
+ }
439
+ if (options == null ? void 0 : options.selectedList) {
440
+ if (flatItem.type === "main" && ((_p = product.discount_list) == null ? void 0 : _p.some((item) => {
441
+ var _a2;
442
+ return (_a2 = options == null ? void 0 : options.selectedList) == null ? void 0 : _a2.some((n) => {
443
+ var _a3;
444
+ return n.discountId === ((_a3 = item.discount) == null ? void 0 : _a3.resource_id);
445
+ });
446
+ }))) {
447
+ isManualDiscount = false;
448
+ }
449
+ if (flatItem.type === "bundle") {
450
+ if (((_q = product.discount_list) == null ? void 0 : _q.some((item) => {
451
+ var _a2;
452
+ return (_a2 = options == null ? void 0 : options.selectedList) == null ? void 0 : _a2.some((n) => {
453
+ var _a3;
454
+ return n.discountId === ((_a3 = item.discount) == null ? void 0 : _a3.resource_id);
455
+ });
456
+ })) || ((_s = (_r = flatItem.parentProduct) == null ? void 0 : _r.discount_list) == null ? void 0 : _s.some((item) => {
457
+ var _a2;
458
+ return (_a2 = options == null ? void 0 : options.selectedList) == null ? void 0 : _a2.some((n) => {
459
+ var _a3;
460
+ return n.discountId === ((_a3 = item.discount) == null ? void 0 : _a3.resource_id);
461
+ });
462
+ }))) {
463
+ isManualDiscount = false;
464
+ }
465
+ }
466
+ }
467
+ if ((options == null ? void 0 : options.selectedList) && ((_t = product.discount_list) == null ? void 0 : _t.some((item) => {
299
468
  var _a2;
300
469
  return (_a2 = options == null ? void 0 : options.selectedList) == null ? void 0 : _a2.some((n) => {
301
470
  var _a3;
@@ -304,45 +473,55 @@ var RulesModule = class extends import_BaseModule.BaseModule {
304
473
  }))) {
305
474
  isManualDiscount = false;
306
475
  }
307
- if (applicableDiscounts.length === 0 || isManualDiscount || (0, import_lodash_es.isBoolean)(product.vouchersApplicable) && !product.vouchersApplicable) {
308
- if (product.isClient) {
309
- processedProductsMap.set(
310
- product._id,
311
- [this.hooks.setProduct(originProduct, {
312
- ...isManualDiscount ? {} : {
313
- origin_total: (0, import_utils2.getProductOriginTotalPrice)({
314
- product: {
315
- original_price: product.original_price
316
- },
317
- bundle: product.bundle,
318
- options: product.options
319
- }),
320
- variant: originProduct._productInit.variant,
321
- original_price: originProduct._productInit.original_price,
322
- total: (0, import_utils2.getProductTotalPrice)({
323
- product: {
324
- price: product.price
325
- },
326
- bundle: product.bundle,
327
- options: product.options
328
- }),
329
- price: product.price
330
- },
331
- discount_list: []
332
- })]
333
- );
476
+ if (applicableDiscounts.length === 0 || isManualDiscount) {
477
+ if (flatItem.type === "main") {
478
+ if (product.isClient) {
479
+ processedProductsMap.set(
480
+ product._id,
481
+ [this.hooks.setProduct(originProduct, {
482
+ ...isManualDiscount ? {} : {
483
+ origin_total: (0, import_utils2.getProductOriginTotalPrice)({
484
+ product: {
485
+ original_price: product.original_price
486
+ },
487
+ bundle: product.bundle,
488
+ options: product.options
489
+ }),
490
+ variant: originProduct._productInit.variant,
491
+ original_price: originProduct._productInit.original_price,
492
+ total: (0, import_utils2.getProductTotalPrice)({
493
+ product: {
494
+ price: product.price
495
+ },
496
+ bundle: product.bundle,
497
+ options: product.options
498
+ }),
499
+ price: product.price
500
+ },
501
+ discount_list: []
502
+ })]
503
+ );
504
+ } else {
505
+ processedProductsMap.set(
506
+ product._id,
507
+ [this.hooks.setProduct(originProduct, {
508
+ ...isManualDiscount ? {} : {
509
+ _id: product._id.split("___")[0] + "___" + index,
510
+ total: product.origin_total || product.total,
511
+ price: product.price,
512
+ main_product_selling_price: product.price
513
+ },
514
+ discount_list: []
515
+ })]
516
+ );
517
+ }
334
518
  } else {
335
- processedProductsMap.set(
336
- product._id,
337
- [this.hooks.setProduct(originProduct, {
338
- ...isManualDiscount ? {} : {
339
- _id: product._id.split("___")[0] + "___" + index,
340
- total: product.origin_total || product.total,
341
- price: product.price
342
- },
343
- discount_list: []
344
- })]
345
- );
519
+ processedFlatItemsMap.set(flatItem._id, [{
520
+ ...flatItem,
521
+ discount_list: [],
522
+ price: flatItem.bundleItem.original_price,
523
+ processed: true
524
+ }]);
346
525
  }
347
526
  return;
348
527
  }
@@ -350,113 +529,508 @@ var RulesModule = class extends import_BaseModule.BaseModule {
350
529
  return;
351
530
  }
352
531
  const isNeedSplit = (selectedDiscount.tag || selectedDiscount.type) === "good_pass";
353
- const splitCount = isNeedSplit ? Math.min(product.quantity || product.num || 1, applicableDiscounts.filter((item) => (item.tag || item.type) === "good_pass").length) : 1;
532
+ const totalQuantity = product.quantity || product.num || 1;
533
+ const availableGoodPassCount = applicableDiscounts.filter((item) => (item.tag || item.type) === "good_pass").length;
534
+ const splitCount = isNeedSplit ? Math.min(totalQuantity, availableGoodPassCount) : 1;
354
535
  const arr = [];
355
- if (splitCount < product.quantity && isNeedSplit) {
356
- arr.push(this.hooks.setProduct(originProduct, {
357
- discount_list: [],
358
- quantity: product.quantity - splitCount,
359
- _id: product._id.split("___")[0]
360
- }));
361
- }
362
- for (let i = 0; i < splitCount; i++) {
363
- const selectedDiscount2 = selectedDiscountCard || applicableDiscounts[i];
364
- usedDiscounts.set(selectedDiscount2.id, true);
365
- const appliedProducts = appliedDiscountProducts.get(selectedDiscount2.id) || [];
366
- let productOriginTotal = product.origin_total || product.total || 0;
367
- if (((_h = product.discount_list) == null ? void 0 : _h.length) && product.origin_total) {
368
- productOriginTotal = product.origin_total;
369
- }
370
- if (Number(((_i = originProduct == null ? void 0 : originProduct._productInit) == null ? void 0 : _i.original_price) || 0) > 0 && product.origin_total && product.total && product.origin_total !== product.total) {
371
- productOriginTotal = product.total;
536
+ if (flatItem.type === "main") {
537
+ if (splitCount < totalQuantity && isNeedSplit) {
538
+ arr.push(this.hooks.setProduct(originProduct, {
539
+ discount_list: [],
540
+ quantity: totalQuantity - splitCount,
541
+ _id: product._id.split("___")[0]
542
+ }));
372
543
  }
373
- const targetProductTotal = (0, import_utils.getDiscountAmount)(selectedDiscount2, productOriginTotal, product.price);
374
- const discountType = selectedDiscount2.tag === "product_discount_card" ? "discount_card" : selectedDiscount2.tag;
375
- const discountDetail = {
376
- amount: new import_decimal.default(productOriginTotal).minus(new import_decimal.default(targetProductTotal)).toNumber(),
377
- type: discountType,
378
- discount: {
379
- discount_card_type: (_j = selectedDiscount2 == null ? void 0 : selectedDiscount2.metadata) == null ? void 0 : _j.discount_card_type,
380
- fixed_amount: new import_decimal.default(productOriginTotal).minus(new import_decimal.default(targetProductTotal)).toNumber(),
381
- resource_id: selectedDiscount2.id,
382
- title: selectedDiscount2.format_title,
383
- original_amount: productOriginTotal,
384
- product_id: originProduct.id,
385
- percent: selectedDiscount2.par_value
544
+ for (let i = 0; i < splitCount; i++) {
545
+ const selectedDiscount2 = selectedDiscountCard || applicableDiscounts[i];
546
+ usedDiscounts.set(selectedDiscount2.id, true);
547
+ const appliedProducts = appliedDiscountProducts.get(selectedDiscount2.id) || [];
548
+ let productOriginTotal = product.origin_total || product.total || 0;
549
+ if (((_u = product.discount_list) == null ? void 0 : _u.length) && product.origin_total) {
550
+ productOriginTotal = product.origin_total;
551
+ }
552
+ 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) {
553
+ productOriginTotal = product.total;
554
+ }
555
+ const targetProductTotal = (0, import_utils.getDiscountAmount)(selectedDiscount2, product.price, product.price);
556
+ const discountType = selectedDiscount2.tag || selectedDiscount2.type;
557
+ const isGoodPass = discountType === "good_pass";
558
+ const amount = new import_decimal.default(product.price).minus(new import_decimal.default(targetProductTotal)).toNumber();
559
+ const discountDetail = {
560
+ amount,
561
+ type: selectedDiscount2.tag === "product_discount_card" ? "discount_card" : discountType,
562
+ discount: {
563
+ discount_card_type: (_w = selectedDiscount2 == null ? void 0 : selectedDiscount2.metadata) == null ? void 0 : _w.discount_card_type,
564
+ fixed_amount: amount,
565
+ resource_id: selectedDiscount2.id,
566
+ title: selectedDiscount2.format_title,
567
+ original_amount: product.price,
568
+ product_id: originProduct.id,
569
+ percent: selectedDiscount2.par_value
570
+ },
571
+ // 前端使用的num数量,为了计算优惠金额
572
+ _num: isGoodPass ? 1 : product.num,
573
+ metadata: {
574
+ num: 1
575
+ }
576
+ };
577
+ appliedProducts.push(discountDetail);
578
+ appliedDiscountProducts.set(selectedDiscount2.id, appliedProducts);
579
+ let total = targetProductTotal;
580
+ if (product.options) {
581
+ total = product.options.reduce((accumulator, currentValue) => {
582
+ const currentPrice = new import_decimal.default(currentValue.price || 0);
583
+ const currentNum = new import_decimal.default(currentValue.num || 0);
584
+ return accumulator.add(currentPrice.mul(currentNum));
585
+ }, new import_decimal.default(total)).toNumber();
586
+ }
587
+ if (product.isClient) {
588
+ debugger;
589
+ arr.push(this.hooks.setProduct(originProduct, {
590
+ discount_list: [discountDetail],
591
+ price: selectedDiscount2.tag === "good_pass" ? 0 : product.price,
592
+ quantity: isNeedSplit ? 1 : product.quantity,
593
+ origin_total: (0, import_utils2.getProductOriginTotalPrice)({
594
+ product: {
595
+ original_price: product.original_price
596
+ },
597
+ bundle: product.bundle,
598
+ options: product.options
599
+ }),
600
+ variant: originProduct._productInit.variant,
601
+ original_price: new import_decimal.default(product.price || 0).toNumber(),
602
+ total
603
+ }));
604
+ } else {
605
+ arr.push(this.hooks.setProduct(originProduct, {
606
+ discount_list: [discountDetail],
607
+ _id: product._id.split("___")[0] + "___" + selectedDiscount2.id + index,
608
+ price: selectedDiscount2.tag === "good_pass" ? 0 : product.price,
609
+ quantity: isNeedSplit ? 1 : product.quantity,
610
+ total,
611
+ origin_total: productOriginTotal,
612
+ main_product_selling_price: targetProductTotal
613
+ }));
386
614
  }
387
- };
388
- if ((selectedDiscount2.tag || selectedDiscount2.type) !== "good_pass") {
389
- discountDetail.num = product.num || 1;
390
615
  }
391
- appliedProducts.push(discountDetail);
392
- appliedDiscountProducts.set(selectedDiscount2.id, appliedProducts);
393
- if (product.isClient) {
394
- arr.push(this.hooks.setProduct(originProduct, {
395
- discount_list: [discountDetail],
396
- price: selectedDiscount2.tag === "good_pass" ? 0 : product.price,
397
- quantity: isNeedSplit ? 1 : product.quantity,
398
- origin_total: (0, import_utils2.getProductOriginTotalPrice)({
399
- product: {
400
- original_price: product.original_price
616
+ processedProductsMap.set(product._id, arr);
617
+ } else {
618
+ const processedItems = [];
619
+ if (isNeedSplit) {
620
+ const discountNum = splitCount;
621
+ const normalNum = totalQuantity - discountNum;
622
+ for (let i = 0; i < discountNum; i++) {
623
+ const selectedDiscount2 = applicableDiscounts[i];
624
+ usedDiscounts.set(selectedDiscount2.id, true);
625
+ const uniqueId = `${flatItem._id}_split_${i}`;
626
+ const discountDetail = {
627
+ amount: product.origin_total,
628
+ type: "good_pass",
629
+ discount: {
630
+ fixed_amount: product.origin_total,
631
+ resource_id: selectedDiscount2.id,
632
+ title: selectedDiscount2.format_title,
633
+ original_amount: product.origin_total,
634
+ product_id: product.id
401
635
  },
402
- bundle: product.bundle,
403
- options: product.options
404
- }),
405
- variant: originProduct._productInit.variant,
406
- original_price: new import_decimal.default(product.price || 0).toNumber(),
407
- total: targetProductTotal
408
- }));
636
+ metadata: {
637
+ // 🔥 使用拆分后的唯一 _id
638
+ custom_product_bundle_map_id: uniqueId,
639
+ num: 1
640
+ },
641
+ _num: 1
642
+ };
643
+ const appliedProducts = appliedDiscountProducts.get(selectedDiscount2.id) || [];
644
+ appliedProducts.push(discountDetail);
645
+ appliedDiscountProducts.set(selectedDiscount2.id, appliedProducts);
646
+ processedItems.push({
647
+ ...flatItem,
648
+ // 🔥 使用唯一的 _id
649
+ _id: uniqueId,
650
+ num: 1,
651
+ quantity: 1,
652
+ price: 0,
653
+ // 商品券价格为0
654
+ total: 0,
655
+ discount_list: [discountDetail],
656
+ processed: true,
657
+ _discountId: selectedDiscount2.id
658
+ });
659
+ }
660
+ if (normalNum > 0) {
661
+ processedItems.push({
662
+ ...flatItem,
663
+ // 🔥 为剩余商品生成唯一的 _id
664
+ _id: `${flatItem._id}_split_rest`,
665
+ num: normalNum,
666
+ quantity: normalNum,
667
+ discount_list: [],
668
+ processed: true
669
+ });
670
+ }
409
671
  } else {
410
- arr.push(this.hooks.setProduct(originProduct, {
411
- discount_list: [discountDetail],
412
- _id: product._id.split("___")[0] + "___" + selectedDiscount2.id + "___" + index,
413
- price: selectedDiscount2.tag === "good_pass" ? 0 : product.price,
414
- quantity: isNeedSplit ? 1 : product.quantity,
672
+ const selectedDiscount2 = selectedDiscountCard || applicableDiscounts[0];
673
+ usedDiscounts.set(selectedDiscount2.id, true);
674
+ const productOriginTotal = product.original_price || product.price || 0;
675
+ const targetProductTotal = (0, import_utils.getDiscountAmount)(
676
+ selectedDiscount2,
677
+ productOriginTotal,
678
+ productOriginTotal
679
+ );
680
+ const uniqueId = flatItem._id;
681
+ const discountDetail = {
682
+ amount: new import_decimal.default(productOriginTotal).minus(targetProductTotal).toNumber() * (product.num || 1),
683
+ type: selectedDiscount2.tag === "product_discount_card" ? "discount_card" : selectedDiscount2.tag,
684
+ discount: {
685
+ discount_card_type: (_x = selectedDiscount2 == null ? void 0 : selectedDiscount2.metadata) == null ? void 0 : _x.discount_card_type,
686
+ fixed_amount: new import_decimal.default(productOriginTotal).minus(targetProductTotal).toNumber(),
687
+ resource_id: selectedDiscount2.id,
688
+ title: selectedDiscount2.format_title,
689
+ original_amount: product.original_price,
690
+ product_id: product.id,
691
+ percent: selectedDiscount2.par_value
692
+ },
693
+ metadata: {
694
+ // 🔥 使用唯一的 _id
695
+ custom_product_bundle_map_id: uniqueId,
696
+ num: product.num || 1
697
+ },
698
+ _num: (product.num || 1) * (((_y = flatItem == null ? void 0 : flatItem.parentProduct) == null ? void 0 : _y.num) || 1)
699
+ };
700
+ const appliedProducts = appliedDiscountProducts.get(selectedDiscount2.id) || [];
701
+ appliedProducts.push(discountDetail);
702
+ appliedDiscountProducts.set(selectedDiscount2.id, appliedProducts);
703
+ processedItems.push({
704
+ ...flatItem,
415
705
  total: targetProductTotal,
416
- origin_total: productOriginTotal
417
- }));
706
+ price: new import_decimal.default(productOriginTotal || 0).minus(discountDetail.discount.fixed_amount).toNumber(),
707
+ discount_list: [discountDetail],
708
+ processed: true
709
+ });
418
710
  }
711
+ processedFlatItemsMap.set(flatItem._id, processedItems);
419
712
  }
420
- console.log(arr, "arrarrarr");
421
- processedProductsMap.set(product._id, arr);
422
713
  });
423
- const processedProductList = [];
424
- productList.forEach((originProduct) => {
425
- const product = this.hooks.getProduct(originProduct);
426
- const getDefaultProduct = () => {
427
- if (product.isClient) {
428
- return this.hooks.setProduct(originProduct, {
429
- discount_list: [],
430
- price: product.price,
431
- origin_total: (0, import_utils2.getProductOriginTotalPrice)({
432
- product: {
433
- original_price: product.original_price
434
- },
435
- bundle: product.bundle,
436
- options: product.options
437
- }),
438
- variant: originProduct._productInit.variant,
439
- original_price: originProduct._productInit.original_price,
440
- total: (0, import_utils2.getProductTotalPrice)({
441
- product: {
714
+ const reconstructProductsWithBundle = (processedProductsMap2, processedFlatItemsMap2, originalProductList) => {
715
+ const result = [];
716
+ originalProductList.forEach((originProduct) => {
717
+ const product = this.hooks.getProduct(originProduct);
718
+ const mainProductArr = processedProductsMap2.get(product._id);
719
+ if (!mainProductArr || mainProductArr.length === 0) {
720
+ const getDefaultProduct = () => {
721
+ if (product.isClient) {
722
+ return this.hooks.setProduct(originProduct, {
723
+ discount_list: [],
724
+ price: product.price,
725
+ origin_total: (0, import_utils2.getProductOriginTotalPrice)({
726
+ product: {
727
+ original_price: product.original_price
728
+ },
729
+ bundle: product.bundle,
730
+ options: product.options
731
+ }),
732
+ variant: originProduct._productInit.variant,
733
+ original_price: originProduct._productInit.original_price,
734
+ total: (0, import_utils2.getProductTotalPrice)({
735
+ product: {
736
+ price: product.price
737
+ },
738
+ bundle: product.bundle,
739
+ options: product.options
740
+ })
741
+ });
742
+ } else {
743
+ return this.hooks.setProduct(originProduct, {
744
+ discount_list: [],
745
+ total: product.total,
746
+ origin_total: product.origin_total,
442
747
  price: product.price
443
- },
444
- bundle: product.bundle,
445
- options: product.options
446
- })
447
- });
748
+ });
749
+ }
750
+ };
751
+ result.push(getDefaultProduct());
752
+ return;
753
+ }
754
+ const hasBundle = product.bundle && Array.isArray(product.bundle) && product.bundle.length > 0;
755
+ if (!hasBundle) {
756
+ result.push(...mainProductArr);
448
757
  } else {
449
- return this.hooks.setProduct(originProduct, {
450
- discount_list: [],
451
- total: product.total,
452
- origin_total: product.origin_total,
453
- price: product.price
454
- });
758
+ const bundleProcessingInfo = /* @__PURE__ */ new Map();
759
+ let hasGoodPassApplied = false;
760
+ if (product.bundle && Array.isArray(product.bundle)) {
761
+ product.bundle.forEach((bundleItem, bundleIndex) => {
762
+ const bundleItemId = `${product._id}_bundle_${bundleIndex}`;
763
+ const processedBundleItems = processedFlatItemsMap2.get(bundleItemId);
764
+ if (!processedBundleItems || processedBundleItems.length === 0) {
765
+ bundleProcessingInfo.set(bundleIndex, [bundleItem]);
766
+ } else {
767
+ bundleProcessingInfo.set(bundleIndex, processedBundleItems);
768
+ const hasGoodPass = processedBundleItems.some(
769
+ (item) => {
770
+ var _a;
771
+ return (_a = item.discount_list) == null ? void 0 : _a.some(
772
+ (discount) => discount.type === "good_pass" || discount.tag === "good_pass"
773
+ );
774
+ }
775
+ );
776
+ if (hasGoodPass) {
777
+ hasGoodPassApplied = true;
778
+ }
779
+ }
780
+ });
781
+ }
782
+ const mainProductQuantity = mainProductArr[0] ? this.hooks.getProduct(mainProductArr[0]).quantity : 1;
783
+ if (hasGoodPassApplied && mainProductArr.length === 1 && mainProductQuantity > 1) {
784
+ const mainProduct = mainProductArr[0];
785
+ const mainProductData = this.hooks.getProduct(mainProduct);
786
+ const newBundleWithDiscount = [];
787
+ (product.bundle || []).forEach((bundleItem, bundleIndex) => {
788
+ const processedItems = bundleProcessingInfo.get(bundleIndex) || [bundleItem];
789
+ if (processedItems.length > 1) {
790
+ processedItems.forEach((item) => {
791
+ const updatedDiscountList2 = (item.discount_list || []).map((discount) => {
792
+ var _a;
793
+ return {
794
+ ...discount,
795
+ metadata: {
796
+ num: item.num,
797
+ custom_product_bundle_map_id: (_a = item.metadata) == null ? void 0 : _a.custom_product_bundle_map_id
798
+ }
799
+ // num: item.num, // 使用拆分后的 num
800
+ };
801
+ });
802
+ newBundleWithDiscount.push({
803
+ ...bundleItem,
804
+ _id: item._id,
805
+ product_id: bundleItem.product_id,
806
+ price: item.price,
807
+ num: item.num,
808
+ discount_list: updatedDiscountList2
809
+ });
810
+ });
811
+ } else {
812
+ const item = processedItems[0];
813
+ if (item.processed) {
814
+ const updatedDiscountList2 = (item.discount_list || []).map((discount) => {
815
+ var _a;
816
+ return {
817
+ ...discount,
818
+ metadata: {
819
+ num: item.num,
820
+ custom_product_bundle_map_id: (_a = item.metadata) == null ? void 0 : _a.custom_product_bundle_map_id
821
+ }
822
+ // num: item.num, // 使用当前的 num
823
+ };
824
+ });
825
+ newBundleWithDiscount.push({
826
+ ...bundleItem,
827
+ _id: item._id,
828
+ product_id: bundleItem.product_id,
829
+ price: item.price,
830
+ num: item.num,
831
+ discount_list: updatedDiscountList2
832
+ });
833
+ } else {
834
+ newBundleWithDiscount.push(item);
835
+ }
836
+ }
837
+ });
838
+ let newTotalWithDiscount = Number(mainProductData.price || 0);
839
+ let newOriginTotalWithDiscount = Number(mainProductData.original_price || mainProductData.price || 0);
840
+ const updatedMainDiscountList = mainProductData.discount_list.map((discount) => {
841
+ var _a, _b;
842
+ if ((_a = discount == null ? void 0 : discount.metadata) == null ? void 0 : _a.custom_product_bundle_map_id) {
843
+ return discount;
844
+ }
845
+ return {
846
+ ...discount,
847
+ // num: 1,
848
+ metadata: {
849
+ custom_product_bundle_map_id: (_b = discount == null ? void 0 : discount.metadata) == null ? void 0 : _b.custom_product_bundle_map_id,
850
+ num: 1
851
+ }
852
+ };
853
+ });
854
+ const mainDiscountList = updatedMainDiscountList.filter((item) => {
855
+ var _a;
856
+ return !((_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a.custom_product_bundle_map_id);
857
+ });
858
+ if (mainDiscountList && mainDiscountList.length > 0) {
859
+ const allDiscountAmount = (0, import_utils.getDiscountListAmountTotal)(mainDiscountList);
860
+ newTotalWithDiscount = new import_decimal.default(mainProductData.price || 0).minus(allDiscountAmount).toNumber() ?? newTotalWithDiscount;
861
+ newOriginTotalWithDiscount = mainProductData.origin_total ?? newOriginTotalWithDiscount;
862
+ if (newBundleWithDiscount.length > 0) {
863
+ newBundleWithDiscount.forEach((item) => {
864
+ var _a, _b, _c;
865
+ newTotalWithDiscount += Number(item.price) * Number(item.num);
866
+ const originalPrice = ((_c = (_b = (_a = item.discount_list) == null ? void 0 : _a[0]) == null ? void 0 : _b.discount) == null ? void 0 : _c.original_amount) || item.price;
867
+ newOriginTotalWithDiscount += Number(originalPrice) * Number(item.num);
868
+ });
869
+ }
870
+ }
871
+ if (product == null ? void 0 : product.options) {
872
+ newTotalWithDiscount = product.options.reduce((accumulator, currentValue) => {
873
+ const currentPrice = new import_decimal.default(currentValue.price || 0);
874
+ const currentNum = new import_decimal.default(currentValue.num || 0);
875
+ return accumulator.add(currentPrice.mul(currentNum));
876
+ }, new import_decimal.default(newTotalWithDiscount)).toNumber();
877
+ }
878
+ result.push(
879
+ this.hooks.setProduct(mainProduct, {
880
+ ...mainProductData,
881
+ _id: `${mainProductData._id.split("___")[0]}___split_discount`,
882
+ quantity: 1,
883
+ discount_list: updatedMainDiscountList,
884
+ bundle: newBundleWithDiscount,
885
+ total: newTotalWithDiscount,
886
+ origin_total: newOriginTotalWithDiscount
887
+ })
888
+ );
889
+ if (mainProductQuantity > 1) {
890
+ const newBundleOriginal = [];
891
+ (product.bundle || []).forEach((bundleItem, bundleIndex) => {
892
+ newBundleOriginal.push({
893
+ ...bundleItem,
894
+ discount_list: []
895
+ });
896
+ });
897
+ let newTotalOriginal = Number(mainProductData.price || 0);
898
+ let newOriginTotalOriginal = Number(mainProductData.original_price || mainProductData.price || 0);
899
+ const updatedMainDiscountListOriginal = mainProductData.discount_list.map((discount) => {
900
+ var _a, _b;
901
+ if ((_a = discount == null ? void 0 : discount.metadata) == null ? void 0 : _a.custom_product_bundle_map_id) {
902
+ return discount;
903
+ }
904
+ return {
905
+ ...discount,
906
+ metadata: {
907
+ num: mainProductQuantity - 1,
908
+ custom_product_bundle_map_id: (_b = discount == null ? void 0 : discount.metadata) == null ? void 0 : _b.custom_product_bundle_map_id
909
+ }
910
+ // num: mainProductQuantity - 1,
911
+ };
912
+ });
913
+ const mainDiscountListOriginal = updatedMainDiscountListOriginal.filter((item) => {
914
+ var _a;
915
+ return !((_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a.custom_product_bundle_map_id);
916
+ });
917
+ if (mainDiscountListOriginal && mainDiscountListOriginal.length > 0) {
918
+ const allDiscountAmount = (0, import_utils.getDiscountListAmount)(mainDiscountListOriginal);
919
+ newTotalOriginal = new import_decimal.default(mainProductData.price || 0).minus(allDiscountAmount).toNumber() ?? newTotalOriginal;
920
+ newOriginTotalOriginal = mainProductData.origin_total ?? newOriginTotalOriginal;
921
+ if (newBundleOriginal.length > 0) {
922
+ newBundleOriginal.forEach((item) => {
923
+ newTotalOriginal += Number(item.price) * Number(item.num);
924
+ newOriginTotalOriginal += Number(item.price) * Number(item.num);
925
+ });
926
+ }
927
+ }
928
+ if (product == null ? void 0 : product.options) {
929
+ newTotalOriginal = product.options.reduce((accumulator, currentValue) => {
930
+ const currentPrice = new import_decimal.default(currentValue.price || 0);
931
+ const currentNum = new import_decimal.default(currentValue.num || 0);
932
+ return accumulator.add(currentPrice.mul(currentNum));
933
+ }, new import_decimal.default(newTotalOriginal)).toNumber();
934
+ }
935
+ result.push(
936
+ this.hooks.setProduct(mainProduct, {
937
+ ...mainProductData,
938
+ _id: `${mainProductData._id.split("___")[0]}___split_normal`,
939
+ quantity: mainProductQuantity - 1,
940
+ discount_list: updatedMainDiscountListOriginal,
941
+ bundle: newBundleOriginal,
942
+ total: newTotalOriginal,
943
+ origin_total: newOriginTotalOriginal
944
+ })
945
+ );
946
+ }
947
+ } else {
948
+ mainProductArr.forEach((mainProduct) => {
949
+ var _a, _b, _c;
950
+ const mainProductData = this.hooks.getProduct(mainProduct);
951
+ const newBundle = [];
952
+ if (product.bundle && Array.isArray(product.bundle)) {
953
+ product.bundle.forEach((bundleItem, bundleIndex) => {
954
+ const bundleItemId = `${product._id}_bundle_${bundleIndex}`;
955
+ const processedBundleItems = processedFlatItemsMap2.get(bundleItemId);
956
+ if (!processedBundleItems || processedBundleItems.length === 0) {
957
+ newBundle.push(bundleItem);
958
+ } else {
959
+ processedBundleItems.forEach((item) => {
960
+ const updatedDiscountList2 = (item.discount_list || []).map((discount) => {
961
+ var _a2;
962
+ return {
963
+ ...discount,
964
+ metadata: {
965
+ num: item.num,
966
+ custom_product_bundle_map_id: (_a2 = discount == null ? void 0 : discount.metadata) == null ? void 0 : _a2.custom_product_bundle_map_id
967
+ }
968
+ // num: item.num, // 使用拆分后的 num
969
+ };
970
+ });
971
+ newBundle.push({
972
+ ...bundleItem,
973
+ _id: item._id,
974
+ product_id: bundleItem.product_id,
975
+ price: item.price,
976
+ num: item.num,
977
+ discount_list: updatedDiscountList2
978
+ });
979
+ });
980
+ }
981
+ });
982
+ }
983
+ let newTotal = Number(mainProductData.price || 0);
984
+ let newOriginTotal = Number(mainProductData.original_price || mainProductData.price || 0);
985
+ 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")));
986
+ if (isManualDiscount) {
987
+ newTotal = mainProductData.total ?? newTotal;
988
+ newOriginTotal = mainProductData.origin_total ?? newOriginTotal;
989
+ } else {
990
+ const mainDiscountList = mainProductData.discount_list.filter((item) => {
991
+ var _a2;
992
+ return !((_a2 = item == null ? void 0 : item.metadata) == null ? void 0 : _a2.custom_product_bundle_map_id);
993
+ });
994
+ if (mainDiscountList && mainDiscountList.length > 0) {
995
+ const allDiscountAmount = (0, import_utils.getDiscountListAmount)(mainDiscountList);
996
+ newTotal = new import_decimal.default(mainProductData.price || 0).minus(allDiscountAmount).toNumber() ?? newTotal;
997
+ newOriginTotal = mainProductData.origin_total ?? newOriginTotal;
998
+ }
999
+ if (newBundle.length > 0) {
1000
+ newBundle.forEach((item) => {
1001
+ var _a2, _b2, _c2;
1002
+ newTotal += Number(item.price) * Number(item.num);
1003
+ 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;
1004
+ newOriginTotal += Number(originalPrice) * Number(item.num);
1005
+ });
1006
+ }
1007
+ }
1008
+ if (product == null ? void 0 : product.options) {
1009
+ newTotal = product.options.reduce((accumulator, currentValue) => {
1010
+ const currentPrice = new import_decimal.default(currentValue.price || 0);
1011
+ const currentNum = new import_decimal.default(currentValue.num || 0);
1012
+ return accumulator.add(currentPrice.mul(currentNum));
1013
+ }, new import_decimal.default(newTotal)).toNumber();
1014
+ }
1015
+ result.push(
1016
+ this.hooks.setProduct(mainProduct, {
1017
+ ...mainProductData,
1018
+ bundle: newBundle,
1019
+ total: newTotal,
1020
+ origin_total: newOriginTotal
1021
+ })
1022
+ );
1023
+ });
1024
+ }
455
1025
  }
456
- };
457
- const arr = processedProductsMap.get(product._id);
458
- (arr == null ? void 0 : arr.length) ? processedProductList.push(...arr) : processedProductList.push(getDefaultProduct());
459
- });
1026
+ });
1027
+ return result;
1028
+ };
1029
+ const processedProductList = reconstructProductsWithBundle(
1030
+ processedProductsMap,
1031
+ processedFlatItemsMap,
1032
+ productList
1033
+ );
460
1034
  const updatedDiscountList = addModeDiscount.map((discount) => {
461
1035
  const applicableProducts = discountApplicability.get(discount.id) || [];
462
1036
  const applicableProductDetails = discountApplicableProducts.get(discount.id) || [];
@@ -517,6 +1091,64 @@ var RulesModule = class extends import_BaseModule.BaseModule {
517
1091
  discountList: [...editModeDiscount, ...updatedDiscountList]
518
1092
  };
519
1093
  }
1094
+ /**
1095
+ * 检查优惠是否符合 PackageSubItemUsageRules 配置
1096
+ * @param discount 优惠券
1097
+ * @param flatItem 扁平化后的商品项(可能是主商品或bundle子商品)
1098
+ * @returns 是否可用
1099
+ */
1100
+ checkPackageSubItemUsageRules(discount, flatItem) {
1101
+ var _a, _b, _c, _d;
1102
+ const limitedData = discount.limited_relation_product_data;
1103
+ const usageRules = limitedData == null ? void 0 : limitedData.package_sub_item_usage_rules;
1104
+ const rules = ["original_price", ...(usageRules == null ? void 0 : usageRules.rules) || []];
1105
+ if (!usageRules) {
1106
+ return true;
1107
+ }
1108
+ const ruleType = usageRules.type;
1109
+ const isMainProduct = flatItem.type === "main";
1110
+ const isBundleItem = flatItem.type === "bundle";
1111
+ if (isMainProduct) {
1112
+ return true;
1113
+ }
1114
+ if (ruleType === "universal_discount") {
1115
+ if (isMainProduct) {
1116
+ return true;
1117
+ }
1118
+ if (isBundleItem) {
1119
+ const priceType = (_a = flatItem.bundleItem) == null ? void 0 : _a.price_type;
1120
+ const priceTypeExt = (_b = flatItem.bundleItem) == null ? void 0 : _b.price_type_ext;
1121
+ const isOriginalPrice = priceType === "markup" && priceTypeExt === "product_price";
1122
+ const isMarkupPrice = priceType === "markup" && (priceTypeExt === "" || !priceTypeExt);
1123
+ if (rules.length > 0) {
1124
+ if (isOriginalPrice && rules.includes("original_price")) {
1125
+ return true;
1126
+ }
1127
+ if (isMarkupPrice && rules.includes("markup_price")) {
1128
+ return true;
1129
+ }
1130
+ return false;
1131
+ }
1132
+ return isOriginalPrice;
1133
+ }
1134
+ return true;
1135
+ }
1136
+ if (ruleType === "package_exclusive") {
1137
+ if (isMainProduct) {
1138
+ return false;
1139
+ }
1140
+ if (isBundleItem) {
1141
+ const priceType = (_c = flatItem.bundleItem) == null ? void 0 : _c.price_type;
1142
+ const priceTypeExt = (_d = flatItem.bundleItem) == null ? void 0 : _d.price_type_ext;
1143
+ return priceType === "markup" && priceTypeExt === "product_price";
1144
+ }
1145
+ return false;
1146
+ }
1147
+ if (ruleType === "single_item_promo") {
1148
+ return isMainProduct;
1149
+ }
1150
+ return true;
1151
+ }
520
1152
  async destroy() {
521
1153
  this.core.effects.offByModuleDestroy(this.name);
522
1154
  await this.core.effects.emit(`${this.name}:onDestroy`, {});