@pisell/pisellos 0.0.478 → 0.0.480

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.
@@ -101,6 +101,18 @@ var getApplicableProducts = function getApplicableProducts(voucher, productsData
101
101
  });
102
102
  };
103
103
 
104
+ /**
105
+ * 计算指定 product_id 在展开后的商品列表中的总 quantity
106
+ * 处理同一 product_id 可能分散在多条记录中的情况(如3个独立的 quantity=1 条目)
107
+ */
108
+ var getTotalQuantityByProductId = function getTotalQuantityByProductId(allProducts, productId) {
109
+ return allProducts.filter(function (p) {
110
+ return p.product_id === productId;
111
+ }).reduce(function (sum, p) {
112
+ return sum + getProductQuantity(p);
113
+ }, 0);
114
+ };
115
+
104
116
  /**
105
117
  * 优惠券处理函数
106
118
  * @param applicableVouchers 可用的券列表
@@ -125,21 +137,22 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
125
137
  return ((_usageMap$get = usageMap.get(walletPassProductId)) === null || _usageMap$get === void 0 ? void 0 : _usageMap$get.get(orderItemProductId)) || 0;
126
138
  };
127
139
 
128
- // 更新指定 Wallet Pass 商品对指定订单商品行的已用卡券次数 +1
140
+ // 更新指定 Wallet Pass 商品对指定订单商品行的已用卡券次数
129
141
  var incrementItemPassUsage = function incrementItemPassUsage(usageMap, walletPassProductId, orderItemProductId) {
142
+ var count = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1;
130
143
  if (!usageMap.has(walletPassProductId)) {
131
144
  usageMap.set(walletPassProductId, new Map());
132
145
  }
133
146
  var innerMap = usageMap.get(walletPassProductId);
134
- innerMap.set(orderItemProductId, (innerMap.get(orderItemProductId) || 0) + 1);
147
+ innerMap.set(orderItemProductId, (innerMap.get(orderItemProductId) || 0) + count);
135
148
  };
136
149
 
137
150
  // 按 maxPassesPerItem 过滤商品:排除已达到单商品可用卡券上限的商品
138
- // maxPassesPerItem 是 per-unit 的限制,总上限 = maxPassesPerItem × quantity
139
- var filterByMaxPassesPerItem = function filterByMaxPassesPerItem(products, usageMap, walletPassProductId, maxPassesPerItem) {
151
+ // maxPassesPerItem 是 per-unit 的限制,总上限 = maxPassesPerItem × 该 product_id 的总 quantity
152
+ var filterByMaxPassesPerItem = function filterByMaxPassesPerItem(products, allProducts, usageMap, walletPassProductId, maxPassesPerItem) {
140
153
  if (maxPassesPerItem <= 0) return products; // 0 = 不限制
141
154
  return products.filter(function (p) {
142
- return getItemPassUsage(usageMap, walletPassProductId, p.product_id) < maxPassesPerItem * getProductQuantity(p);
155
+ return getItemPassUsage(usageMap, walletPassProductId, p.product_id) < maxPassesPerItem * getTotalQuantityByProductId(allProducts, p.product_id);
143
156
  });
144
157
  };
145
158
  // ================================================================
@@ -176,7 +189,7 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
176
189
 
177
190
  // 按 maxPassesPerItem 过滤:排除已达到单商品可用卡券上限的商品
178
191
  if (itemPassUsage) {
179
- applicableProducts = filterByMaxPassesPerItem(applicableProducts, itemPassUsage, voucher.product_id, maxPassesPerItem);
192
+ applicableProducts = filterByMaxPassesPerItem(applicableProducts, productsData, itemPassUsage, voucher.product_id, maxPassesPerItem);
180
193
  }
181
194
  if (applicableProducts.length === 0) {
182
195
  return new Decimal(0);
@@ -218,12 +231,16 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
218
231
  }, new Decimal(0));
219
232
  }
220
233
  } else {
221
- // 非跨商品券:只能抵扣单个商品(剩余金额最高的)
234
+ // 非跨商品券:选择单价最高的商品(优先抵扣高价商品)
222
235
  var maxProduct = applicableProducts.reduce(function (max, p) {
223
- return p[amountField].greaterThan(max[amountField]) ? p : max;
236
+ return p[unitPriceField].greaterThan(max[unitPriceField]) ? p : max;
224
237
  });
225
- // allowCrossProduct=false 时,applicableProductLimit 不生效,直接使用全部可抵扣数量
226
- finalApplicableAmount = maxProduct[amountField];
238
+ // maxPassesPerItem 限制每张券最多抵扣的单位数
239
+ if (maxPassesPerItem > 0) {
240
+ finalApplicableAmount = Decimal.min(maxProduct[unitPriceField].times(maxPassesPerItem), maxProduct[amountField]);
241
+ } else {
242
+ finalApplicableAmount = maxProduct[amountField];
243
+ }
227
244
  }
228
245
 
229
246
  // 返回最小值
@@ -284,7 +301,7 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
284
301
  var availableAfterPassLimit = getApplicableProducts(voucher, productsData).filter(function (p) {
285
302
  return p[amountField].greaterThan(0);
286
303
  }).filter(function (p) {
287
- return getItemPassUsage(itemPassUsage, product_id, p.product_id) < maxPassesPerItem * getProductQuantity(p);
304
+ return getItemPassUsage(itemPassUsage, product_id, p.product_id) < maxPassesPerItem * getTotalQuantityByProductId(productsData, p.product_id);
288
305
  });
289
306
  if (availableAfterPassLimit.length === 0) {
290
307
  return {
@@ -381,7 +398,7 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
381
398
  });
382
399
 
383
400
  // 按 maxPassesPerItem 过滤:排除已达到单商品可用卡券上限的商品
384
- applicableProducts = filterByMaxPassesPerItem(applicableProducts, itemPassUsageMap, product_id, maxPassesPerItem);
401
+ applicableProducts = filterByMaxPassesPerItem(applicableProducts, productsForRecommendation, itemPassUsageMap, product_id, maxPassesPerItem);
385
402
  if (applicableProducts.length === 0) return false;
386
403
 
387
404
  // ========== 关键修改:在应用券之前,基于当前剩余金额计算 _available_max_amount ==========
@@ -423,12 +440,16 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
423
440
  }, new Decimal(0));
424
441
  }
425
442
  } else {
426
- // 非跨商品券:单个剩余金额最高的商品
443
+ // 非跨商品券:选择单价最高的商品(优先抵扣高价商品)
427
444
  var maxProduct = applicableProducts.reduce(function (max, p) {
428
- return p[amountField].greaterThan(max[amountField]) ? p : max;
445
+ return p[unitPriceField].greaterThan(max[unitPriceField]) ? p : max;
429
446
  });
430
- // allowCrossProduct=false 时,applicableProductLimit 不生效,直接使用全部剩余金额
431
- calculatedAvailableMaxAmount = maxProduct[amountField];
447
+ // maxPassesPerItem 限制每张券最多抵扣的单位数
448
+ if (maxPassesPerItem > 0) {
449
+ calculatedAvailableMaxAmount = Decimal.min(maxProduct[unitPriceField].times(maxPassesPerItem), maxProduct[amountField]);
450
+ } else {
451
+ calculatedAvailableMaxAmount = maxProduct[amountField];
452
+ }
432
453
  }
433
454
 
434
455
  // 取最小值:min(recommended_usage_amount, maxDeductionAmount, 适用商品金额, 订单剩余金额)
@@ -482,12 +503,17 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
482
503
  _iterator3.f();
483
504
  }
484
505
  } else {
485
- // 非跨商品券:只抵扣一个商品(剩余金额最高的)
486
- // allowCrossProduct=false 时,applicableProductLimit 不生效
506
+ // 非跨商品券:选择单价最高的商品(优先抵扣高价商品)
487
507
  var targetProduct = applicableProducts.reduce(function (max, p) {
488
- return p[amountField].greaterThan(max[amountField]) ? p : max;
508
+ return p[unitPriceField].greaterThan(max[unitPriceField]) ? p : max;
489
509
  });
490
- var _actualDeductAmount = Decimal.min(deductionLeft, targetProduct[amountField]);
510
+
511
+ // maxPassesPerItem 限制每张券最多抵扣的单位数
512
+ var _maxDeductForProduct = targetProduct[amountField];
513
+ if (maxPassesPerItem > 0) {
514
+ _maxDeductForProduct = Decimal.min(targetProduct[unitPriceField].times(maxPassesPerItem), targetProduct[amountField]);
515
+ }
516
+ var _actualDeductAmount = Decimal.min(deductionLeft, _maxDeductForProduct);
491
517
 
492
518
  // 计算实际抵扣的数量
493
519
  var _actualDeductQty = Math.ceil(_actualDeductAmount.dividedBy(targetProduct[unitPriceField]).toNumber());
@@ -511,9 +537,9 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
511
537
  // 更新券使用次数(按 product_id 统计)
512
538
  usedVoucherCounts.set(product_id, (usedVoucherCounts.get(product_id) || 0) + 1);
513
539
 
514
- // 更新 maxPassesPerItem 追踪:记录每个被抵扣的商品行
540
+ // 更新 maxPassesPerItem 追踪:按实际抵扣数量递增
515
541
  deductionDetails.forEach(function (detail) {
516
- incrementItemPassUsage(itemPassUsageMap, product_id, detail.product_id);
542
+ incrementItemPassUsage(itemPassUsageMap, product_id, detail.product_id, detail.deductQuantity);
517
543
  });
518
544
 
519
545
  // 添加到推荐列表(包含基于当前剩余金额计算的 available_max_amount)
@@ -605,16 +631,17 @@ export function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmo
605
631
  return ((_itemPassUsageMap$get = itemPassUsageMap.get(walletPassProductId)) === null || _itemPassUsageMap$get === void 0 ? void 0 : _itemPassUsageMap$get.get(orderItemProductId)) || 0;
606
632
  };
607
633
  var incrementItemPassUsage = function incrementItemPassUsage(walletPassProductId, orderItemProductId) {
634
+ var count = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
608
635
  if (!itemPassUsageMap.has(walletPassProductId)) {
609
636
  itemPassUsageMap.set(walletPassProductId, new Map());
610
637
  }
611
638
  var innerMap = itemPassUsageMap.get(walletPassProductId);
612
- innerMap.set(orderItemProductId, (innerMap.get(orderItemProductId) || 0) + 1);
639
+ innerMap.set(orderItemProductId, (innerMap.get(orderItemProductId) || 0) + count);
613
640
  };
614
641
  var filterByMaxPassesPerItem = function filterByMaxPassesPerItem(products, walletPassProductId, maxPassesPerItem) {
615
642
  if (maxPassesPerItem <= 0) return products; // 0 = 不限制
616
643
  return products.filter(function (p) {
617
- return getItemPassUsage(walletPassProductId, p.product_id) < maxPassesPerItem * getProductQuantity(p);
644
+ return getItemPassUsage(walletPassProductId, p.product_id) < maxPassesPerItem * getTotalQuantityByProductId(productsForCalc, p.product_id);
618
645
  });
619
646
  };
620
647
 
@@ -702,12 +729,17 @@ export function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmo
702
729
  _iterator4.f();
703
730
  }
704
731
  } else {
705
- // 非跨商品券:只抵扣一个商品(剩余金额最高的)
706
- // allowCrossProduct=false 时,applicableProductLimit 不生效
732
+ // 非跨商品券:选择单价最高的商品(优先抵扣高价商品)
707
733
  var targetProduct = applicableProducts.reduce(function (max, p) {
708
- return p[amountField].greaterThan(max[amountField]) ? p : max;
734
+ return p[unitPriceField].greaterThan(max[unitPriceField]) ? p : max;
709
735
  });
710
- var _actualDeductAmount2 = Decimal.min(deductionLeft, targetProduct[amountField]);
736
+
737
+ // maxPassesPerItem 限制每张券最多抵扣的单位数
738
+ var _maxDeductForProduct2 = targetProduct[amountField];
739
+ if (maxPassesPerItem > 0) {
740
+ _maxDeductForProduct2 = Decimal.min(targetProduct[unitPriceField].times(maxPassesPerItem), targetProduct[amountField]);
741
+ }
742
+ var _actualDeductAmount2 = Decimal.min(deductionLeft, _maxDeductForProduct2);
711
743
 
712
744
  // 计算实际抵扣的数量
713
745
  var _actualDeductQty2 = Math.ceil(_actualDeductAmount2.dividedBy(targetProduct[unitPriceField]).toNumber());
@@ -728,9 +760,9 @@ export function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmo
728
760
  // 更新订单剩余金额
729
761
  remainingOrderAmount = remainingOrderAmount.minus(totalDeducted);
730
762
 
731
- // 更新 maxPassesPerItem 追踪:记录每个被抵扣的商品行
763
+ // 更新 maxPassesPerItem 追踪:按实际抵扣数量递增
732
764
  deductionDetails.forEach(function (detail) {
733
- incrementItemPassUsage(selectedVoucher.product_id, detail.product_id);
765
+ incrementItemPassUsage(selectedVoucher.product_id, detail.product_id, detail.deductQuantity);
734
766
  });
735
767
  selectedWithDetails.push(_objectSpread(_objectSpread({}, selectedVoucher), {}, {
736
768
  actualDeduction: totalDeducted.toNumber(),
@@ -844,12 +876,16 @@ export function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmo
844
876
  }, new Decimal(0));
845
877
  }
846
878
  } else {
847
- // 非跨商品券:单个剩余金额最高的商品
848
- // allowCrossProduct=false 时,applicableProductLimit 不生效
879
+ // 非跨商品券:选择单价最高的商品(优先抵扣高价商品)
849
880
  var maxProduct = applicableProducts.reduce(function (max, p) {
850
- return p[amountField].greaterThan(max[amountField]) ? p : max;
881
+ return p[unitPriceField].greaterThan(max[unitPriceField]) ? p : max;
851
882
  });
852
- calculatedMaxAmount = maxProduct[amountField];
883
+ // maxPassesPerItem 限制每张券最多抵扣的单位数
884
+ if (maxPassesPerItem > 0) {
885
+ calculatedMaxAmount = Decimal.min(maxProduct[unitPriceField].times(maxPassesPerItem), maxProduct[amountField]);
886
+ } else {
887
+ calculatedMaxAmount = maxProduct[amountField];
888
+ }
853
889
  }
854
890
  calculatedMaxAmount = Decimal.min(baseAmount, calculatedMaxAmount, remainingOrderAmount);
855
891
  if (calculatedMaxAmount.lessThanOrEqualTo(0)) {
@@ -86,6 +86,9 @@ var getApplicableProducts = (voucher, productsData) => {
86
86
  }
87
87
  return productsData.filter((p) => applicableProductIds.includes(p.product_id));
88
88
  };
89
+ var getTotalQuantityByProductId = (allProducts, productId) => {
90
+ return allProducts.filter((p) => p.product_id === productId).reduce((sum, p) => sum + getProductQuantity(p), 0);
91
+ };
89
92
  function processVouchers(applicableVouchers, orderTotalAmount, products) {
90
93
  console.log(products, "products123");
91
94
  const productsCopy = expandProductsWithBundleItems(products, true);
@@ -94,18 +97,18 @@ function processVouchers(applicableVouchers, orderTotalAmount, products) {
94
97
  var _a;
95
98
  return ((_a = usageMap.get(walletPassProductId)) == null ? void 0 : _a.get(orderItemProductId)) || 0;
96
99
  };
97
- const incrementItemPassUsage = (usageMap, walletPassProductId, orderItemProductId) => {
100
+ const incrementItemPassUsage = (usageMap, walletPassProductId, orderItemProductId, count = 1) => {
98
101
  if (!usageMap.has(walletPassProductId)) {
99
102
  usageMap.set(walletPassProductId, /* @__PURE__ */ new Map());
100
103
  }
101
104
  const innerMap = usageMap.get(walletPassProductId);
102
- innerMap.set(orderItemProductId, (innerMap.get(orderItemProductId) || 0) + 1);
105
+ innerMap.set(orderItemProductId, (innerMap.get(orderItemProductId) || 0) + count);
103
106
  };
104
- const filterByMaxPassesPerItem = (products2, usageMap, walletPassProductId, maxPassesPerItem) => {
107
+ const filterByMaxPassesPerItem = (products2, allProducts, usageMap, walletPassProductId, maxPassesPerItem) => {
105
108
  if (maxPassesPerItem <= 0)
106
109
  return products2;
107
110
  return products2.filter(
108
- (p) => getItemPassUsage(usageMap, walletPassProductId, p.product_id) < maxPassesPerItem * getProductQuantity(p)
111
+ (p) => getItemPassUsage(usageMap, walletPassProductId, p.product_id) < maxPassesPerItem * getTotalQuantityByProductId(allProducts, p.product_id)
109
112
  );
110
113
  };
111
114
  const calculateAvailableMaxAmount = (voucher, productsData, itemPassUsage) => {
@@ -120,7 +123,7 @@ function processVouchers(applicableVouchers, orderTotalAmount, products) {
120
123
  const amountField = deductTaxAndFee ? "remainingAmountWithTax" : "remainingAmountPure";
121
124
  let applicableProducts = getApplicableProducts(voucher, productsData).filter((p) => p[amountField].greaterThan(0));
122
125
  if (itemPassUsage) {
123
- applicableProducts = filterByMaxPassesPerItem(applicableProducts, itemPassUsage, voucher.product_id, maxPassesPerItem);
126
+ applicableProducts = filterByMaxPassesPerItem(applicableProducts, productsData, itemPassUsage, voucher.product_id, maxPassesPerItem);
124
127
  }
125
128
  if (applicableProducts.length === 0) {
126
129
  return new import_decimal.default(0);
@@ -150,9 +153,16 @@ function processVouchers(applicableVouchers, orderTotalAmount, products) {
150
153
  }
151
154
  } else {
152
155
  const maxProduct = applicableProducts.reduce(
153
- (max, p) => p[amountField].greaterThan(max[amountField]) ? p : max
156
+ (max, p) => p[unitPriceField].greaterThan(max[unitPriceField]) ? p : max
154
157
  );
155
- finalApplicableAmount = maxProduct[amountField];
158
+ if (maxPassesPerItem > 0) {
159
+ finalApplicableAmount = import_decimal.default.min(
160
+ maxProduct[unitPriceField].times(maxPassesPerItem),
161
+ maxProduct[amountField]
162
+ );
163
+ } else {
164
+ finalApplicableAmount = maxProduct[amountField];
165
+ }
156
166
  }
157
167
  return import_decimal.default.min(baseAmount, finalApplicableAmount, remainingOrderAmount);
158
168
  };
@@ -179,7 +189,7 @@ function processVouchers(applicableVouchers, orderTotalAmount, products) {
179
189
  if (maxPassesPerItem > 0 && itemPassUsage) {
180
190
  const deductTaxAndFee = (config == null ? void 0 : config.deductTaxAndFee) ?? true;
181
191
  const amountField = deductTaxAndFee ? "remainingAmountWithTax" : "remainingAmountPure";
182
- const availableAfterPassLimit = getApplicableProducts(voucher, productsData).filter((p) => p[amountField].greaterThan(0)).filter((p) => getItemPassUsage(itemPassUsage, product_id, p.product_id) < maxPassesPerItem * getProductQuantity(p));
192
+ const availableAfterPassLimit = getApplicableProducts(voucher, productsData).filter((p) => p[amountField].greaterThan(0)).filter((p) => getItemPassUsage(itemPassUsage, product_id, p.product_id) < maxPassesPerItem * getTotalQuantityByProductId(productsData, p.product_id));
183
193
  if (availableAfterPassLimit.length === 0) {
184
194
  return { isAvailable: false, reasonCode: "max_passes_per_item_reached" };
185
195
  }
@@ -229,7 +239,7 @@ function processVouchers(applicableVouchers, orderTotalAmount, products) {
229
239
  voucher,
230
240
  productsForRecommendation
231
241
  ).filter((p) => p[amountField].greaterThan(0));
232
- applicableProducts = filterByMaxPassesPerItem(applicableProducts, itemPassUsageMap, product_id, maxPassesPerItem);
242
+ applicableProducts = filterByMaxPassesPerItem(applicableProducts, productsForRecommendation, itemPassUsageMap, product_id, maxPassesPerItem);
233
243
  if (applicableProducts.length === 0)
234
244
  return false;
235
245
  const usageAmount = typeof voucher.edit_current_amount === "number" ? voucher.edit_current_amount : getRecommendedAmount(voucher);
@@ -262,9 +272,16 @@ function processVouchers(applicableVouchers, orderTotalAmount, products) {
262
272
  }
263
273
  } else {
264
274
  const maxProduct = applicableProducts.reduce(
265
- (max, p) => p[amountField].greaterThan(max[amountField]) ? p : max
275
+ (max, p) => p[unitPriceField].greaterThan(max[unitPriceField]) ? p : max
266
276
  );
267
- calculatedAvailableMaxAmount = maxProduct[amountField];
277
+ if (maxPassesPerItem > 0) {
278
+ calculatedAvailableMaxAmount = import_decimal.default.min(
279
+ maxProduct[unitPriceField].times(maxPassesPerItem),
280
+ maxProduct[amountField]
281
+ );
282
+ } else {
283
+ calculatedAvailableMaxAmount = maxProduct[amountField];
284
+ }
268
285
  }
269
286
  const availableMaxAmount = import_decimal.default.min(
270
287
  baseAmount,
@@ -308,9 +325,16 @@ function processVouchers(applicableVouchers, orderTotalAmount, products) {
308
325
  }
309
326
  } else {
310
327
  const targetProduct = applicableProducts.reduce(
311
- (max, p) => p[amountField].greaterThan(max[amountField]) ? p : max
328
+ (max, p) => p[unitPriceField].greaterThan(max[unitPriceField]) ? p : max
312
329
  );
313
- const actualDeductAmount = import_decimal.default.min(deductionLeft, targetProduct[amountField]);
330
+ let maxDeductForProduct = targetProduct[amountField];
331
+ if (maxPassesPerItem > 0) {
332
+ maxDeductForProduct = import_decimal.default.min(
333
+ targetProduct[unitPriceField].times(maxPassesPerItem),
334
+ targetProduct[amountField]
335
+ );
336
+ }
337
+ const actualDeductAmount = import_decimal.default.min(deductionLeft, maxDeductForProduct);
314
338
  const actualDeductQty = Math.ceil(actualDeductAmount.dividedBy(targetProduct[unitPriceField]).toNumber());
315
339
  targetProduct[amountField] = targetProduct[amountField].minus(actualDeductAmount);
316
340
  deductionLeft = deductionLeft.minus(actualDeductAmount);
@@ -327,7 +351,7 @@ function processVouchers(applicableVouchers, orderTotalAmount, products) {
327
351
  remainingOrderAmount = remainingOrderAmount.minus(totalDeducted);
328
352
  usedVoucherCounts.set(product_id, (usedVoucherCounts.get(product_id) || 0) + 1);
329
353
  deductionDetails.forEach((detail) => {
330
- incrementItemPassUsage(itemPassUsageMap, product_id, detail.product_id);
354
+ incrementItemPassUsage(itemPassUsageMap, product_id, detail.product_id, detail.deductQuantity);
331
355
  });
332
356
  recommendedVouchers.push({
333
357
  ...voucher,
@@ -375,18 +399,18 @@ function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, pr
375
399
  var _a;
376
400
  return ((_a = itemPassUsageMap.get(walletPassProductId)) == null ? void 0 : _a.get(orderItemProductId)) || 0;
377
401
  };
378
- const incrementItemPassUsage = (walletPassProductId, orderItemProductId) => {
402
+ const incrementItemPassUsage = (walletPassProductId, orderItemProductId, count = 1) => {
379
403
  if (!itemPassUsageMap.has(walletPassProductId)) {
380
404
  itemPassUsageMap.set(walletPassProductId, /* @__PURE__ */ new Map());
381
405
  }
382
406
  const innerMap = itemPassUsageMap.get(walletPassProductId);
383
- innerMap.set(orderItemProductId, (innerMap.get(orderItemProductId) || 0) + 1);
407
+ innerMap.set(orderItemProductId, (innerMap.get(orderItemProductId) || 0) + count);
384
408
  };
385
409
  const filterByMaxPassesPerItem = (products2, walletPassProductId, maxPassesPerItem) => {
386
410
  if (maxPassesPerItem <= 0)
387
411
  return products2;
388
412
  return products2.filter(
389
- (p) => getItemPassUsage(walletPassProductId, p.product_id) < maxPassesPerItem * getProductQuantity(p)
413
+ (p) => getItemPassUsage(walletPassProductId, p.product_id) < maxPassesPerItem * getTotalQuantityByProductId(productsForCalc, p.product_id)
390
414
  );
391
415
  };
392
416
  selectedVouchers.forEach((selectedVoucher) => {
@@ -449,9 +473,16 @@ function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, pr
449
473
  }
450
474
  } else {
451
475
  const targetProduct = applicableProducts.reduce(
452
- (max, p) => p[amountField].greaterThan(max[amountField]) ? p : max
476
+ (max, p) => p[unitPriceField].greaterThan(max[unitPriceField]) ? p : max
453
477
  );
454
- const actualDeductAmount = import_decimal.default.min(deductionLeft, targetProduct[amountField]);
478
+ let maxDeductForProduct = targetProduct[amountField];
479
+ if (maxPassesPerItem > 0) {
480
+ maxDeductForProduct = import_decimal.default.min(
481
+ targetProduct[unitPriceField].times(maxPassesPerItem),
482
+ targetProduct[amountField]
483
+ );
484
+ }
485
+ const actualDeductAmount = import_decimal.default.min(deductionLeft, maxDeductForProduct);
455
486
  const actualDeductQty = Math.ceil(actualDeductAmount.dividedBy(targetProduct[unitPriceField]).toNumber());
456
487
  targetProduct[amountField] = targetProduct[amountField].minus(actualDeductAmount);
457
488
  deductionLeft = deductionLeft.minus(actualDeductAmount);
@@ -466,7 +497,7 @@ function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, pr
466
497
  const totalDeducted = maxDeduction.minus(deductionLeft);
467
498
  remainingOrderAmount = remainingOrderAmount.minus(totalDeducted);
468
499
  deductionDetails.forEach((detail) => {
469
- incrementItemPassUsage(selectedVoucher.product_id, detail.product_id);
500
+ incrementItemPassUsage(selectedVoucher.product_id, detail.product_id, detail.deductQuantity);
470
501
  });
471
502
  selectedWithDetails.push({
472
503
  ...selectedVoucher,
@@ -550,9 +581,16 @@ function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, pr
550
581
  }
551
582
  } else {
552
583
  const maxProduct = applicableProducts.reduce(
553
- (max, p) => p[amountField].greaterThan(max[amountField]) ? p : max
584
+ (max, p) => p[unitPriceField].greaterThan(max[unitPriceField]) ? p : max
554
585
  );
555
- calculatedMaxAmount = maxProduct[amountField];
586
+ if (maxPassesPerItem > 0) {
587
+ calculatedMaxAmount = import_decimal.default.min(
588
+ maxProduct[unitPriceField].times(maxPassesPerItem),
589
+ maxProduct[amountField]
590
+ );
591
+ } else {
592
+ calculatedMaxAmount = maxProduct[amountField];
593
+ }
556
594
  }
557
595
  calculatedMaxAmount = import_decimal.default.min(
558
596
  baseAmount,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "0.0.478",
4
+ "version": "0.0.480",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",