@pisell/pisellos 2.1.106 → 2.1.107

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.
@@ -41,7 +41,7 @@ export interface Voucher {
41
41
  allowCrossProduct: boolean;
42
42
  /** 可用商品数量上限 (仅多商品) 默认为0,表示不限制商品数量。 */
43
43
  applicableProductLimit: number;
44
- /** 单商品可用卡券上限(同一 Wallet Pass 商品生成的卡券对同一商品行最多抵扣次数)。默认为 0,表示不限制。 */
44
+ /** 单商品可用卡券上限(同一 Wallet Pass 商品生成的卡券对同一商品的每个 unit 最多抵扣次数,总上限 = maxPassesPerItem × quantity)。默认为 0,表示不限制。 */
45
45
  maxPassesPerItem: number;
46
46
  };
47
47
  }
@@ -129,7 +129,7 @@ export interface EvaluatorInput {
129
129
  allowCrossProduct: boolean;
130
130
  /** 可用商品数量上限 (仅多商品) 默认为0,表示不限制商品数量。 */
131
131
  applicableProductLimit: number;
132
- /** 单商品可用卡券上限(同一 Wallet Pass 商品生成的卡券对同一商品行最多抵扣次数)。默认为 0,表示不限制。 */
132
+ /** 单商品可用卡券上限(同一 Wallet Pass 商品生成的卡券对同一商品的每个 unit 最多抵扣次数,总上限 = maxPassesPerItem × quantity)。默认为 0,表示不限制。 */
133
133
  maxPassesPerItem: number;
134
134
  }>[];
135
135
  }
@@ -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,20 +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
- 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) {
139
153
  if (maxPassesPerItem <= 0) return products; // 0 = 不限制
140
154
  return products.filter(function (p) {
141
- return getItemPassUsage(usageMap, walletPassProductId, p.product_id) < maxPassesPerItem;
155
+ return getItemPassUsage(usageMap, walletPassProductId, p.product_id) < maxPassesPerItem * getTotalQuantityByProductId(allProducts, p.product_id);
142
156
  });
143
157
  };
144
158
  // ================================================================
@@ -175,7 +189,7 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
175
189
 
176
190
  // 按 maxPassesPerItem 过滤:排除已达到单商品可用卡券上限的商品
177
191
  if (itemPassUsage) {
178
- applicableProducts = filterByMaxPassesPerItem(applicableProducts, itemPassUsage, voucher.product_id, maxPassesPerItem);
192
+ applicableProducts = filterByMaxPassesPerItem(applicableProducts, productsData, itemPassUsage, voucher.product_id, maxPassesPerItem);
179
193
  }
180
194
  if (applicableProducts.length === 0) {
181
195
  return new Decimal(0);
@@ -217,16 +231,16 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
217
231
  }, new Decimal(0));
218
232
  }
219
233
  } else {
220
- // 非跨商品券:只能抵扣单个商品(剩余金额最高的)
234
+ // 非跨商品券:选择单价最高的商品(优先抵扣高价商品)
221
235
  var maxProduct = applicableProducts.reduce(function (max, p) {
222
- return p[amountField].greaterThan(max[amountField]) ? p : max;
236
+ return p[unitPriceField].greaterThan(max[unitPriceField]) ? p : max;
223
237
  });
224
- // 动态计算当前可抵扣数量
225
- var _currentAvailableQty = Math.ceil(maxProduct[amountField].dividedBy(maxProduct[unitPriceField]).toNumber());
226
- // 非跨商品券也受 applicableProductLimit 限制
227
- var _deductQty = applicableProductLimit > 0 ? Math.min(_currentAvailableQty, applicableProductLimit) : _currentAvailableQty;
228
- // 实际可抵扣金额 = min(数量 * 单价, 剩余金额)
229
- finalApplicableAmount = Decimal.min(maxProduct[unitPriceField].times(_deductQty), 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
+ }
230
244
  }
231
245
 
232
246
  // 返回最小值
@@ -287,7 +301,7 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
287
301
  var availableAfterPassLimit = getApplicableProducts(voucher, productsData).filter(function (p) {
288
302
  return p[amountField].greaterThan(0);
289
303
  }).filter(function (p) {
290
- return getItemPassUsage(itemPassUsage, product_id, p.product_id) < maxPassesPerItem;
304
+ return getItemPassUsage(itemPassUsage, product_id, p.product_id) < maxPassesPerItem * getTotalQuantityByProductId(productsData, p.product_id);
291
305
  });
292
306
  if (availableAfterPassLimit.length === 0) {
293
307
  return {
@@ -384,7 +398,7 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
384
398
  });
385
399
 
386
400
  // 按 maxPassesPerItem 过滤:排除已达到单商品可用卡券上限的商品
387
- applicableProducts = filterByMaxPassesPerItem(applicableProducts, itemPassUsageMap, product_id, maxPassesPerItem);
401
+ applicableProducts = filterByMaxPassesPerItem(applicableProducts, productsForRecommendation, itemPassUsageMap, product_id, maxPassesPerItem);
388
402
  if (applicableProducts.length === 0) return false;
389
403
 
390
404
  // ========== 关键修改:在应用券之前,基于当前剩余金额计算 _available_max_amount ==========
@@ -426,15 +440,16 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
426
440
  }, new Decimal(0));
427
441
  }
428
442
  } else {
429
- // 非跨商品券:单个剩余金额最高的商品,也受 applicableProductLimit 限制
443
+ // 非跨商品券:选择单价最高的商品(优先抵扣高价商品)
430
444
  var maxProduct = applicableProducts.reduce(function (max, p) {
431
- return p[amountField].greaterThan(max[amountField]) ? p : max;
445
+ return p[unitPriceField].greaterThan(max[unitPriceField]) ? p : max;
432
446
  });
433
- // 动态计算当前可抵扣数量
434
- var _currentAvailableQty2 = Math.ceil(maxProduct[amountField].dividedBy(maxProduct[unitPriceField]).toNumber());
435
- var _deductQty2 = applicableProductLimit > 0 ? Math.min(_currentAvailableQty2, applicableProductLimit) : _currentAvailableQty2;
436
- // 实际可抵扣金额 = min(数量 * 单价, 剩余金额)
437
- calculatedAvailableMaxAmount = Decimal.min(maxProduct[unitPriceField].times(_deductQty2), 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
+ }
438
453
  }
439
454
 
440
455
  // 取最小值:min(recommended_usage_amount, maxDeductionAmount, 适用商品金额, 订单剩余金额)
@@ -459,8 +474,8 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
459
474
  if (deductionLeft.lessThanOrEqualTo(0) || _remainingLimit <= 0) break;
460
475
 
461
476
  // 动态计算当前可抵扣数量 = ceil(剩余金额 / 单价)
462
- var _currentAvailableQty3 = Math.ceil(_product[amountField].dividedBy(_product[unitPriceField]).toNumber());
463
- var availableQty = Math.min(_currentAvailableQty3, _remainingLimit);
477
+ var _currentAvailableQty = Math.ceil(_product[amountField].dividedBy(_product[unitPriceField]).toNumber());
478
+ var availableQty = Math.min(_currentAvailableQty, _remainingLimit);
464
479
 
465
480
  // 计算本商品最大可抵扣金额 = min(数量 * 单价, 剩余金额)
466
481
  var maxDeductForProduct = Decimal.min(_product[unitPriceField].times(availableQty), _product[amountField]);
@@ -488,17 +503,16 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
488
503
  _iterator3.f();
489
504
  }
490
505
  } else {
491
- // 非跨商品券:只抵扣一个商品(剩余金额最高的),也受 applicableProductLimit 限制
506
+ // 非跨商品券:选择单价最高的商品(优先抵扣高价商品)
492
507
  var targetProduct = applicableProducts.reduce(function (max, p) {
493
- return p[amountField].greaterThan(max[amountField]) ? p : max;
508
+ return p[unitPriceField].greaterThan(max[unitPriceField]) ? p : max;
494
509
  });
495
510
 
496
- // 动态计算当前可抵扣数量
497
- var _currentAvailableQty4 = Math.ceil(targetProduct[amountField].dividedBy(targetProduct[unitPriceField]).toNumber());
498
- var _availableQty = applicableProductLimit > 0 ? Math.min(_currentAvailableQty4, applicableProductLimit) : _currentAvailableQty4;
499
-
500
- // 计算本商品最大可抵扣金额 = min(数量 * 单价, 剩余金额)
501
- var _maxDeductForProduct = Decimal.min(targetProduct[unitPriceField].times(_availableQty), targetProduct[amountField]);
511
+ // maxPassesPerItem 限制每张券最多抵扣的单位数
512
+ var _maxDeductForProduct = targetProduct[amountField];
513
+ if (maxPassesPerItem > 0) {
514
+ _maxDeductForProduct = Decimal.min(targetProduct[unitPriceField].times(maxPassesPerItem), targetProduct[amountField]);
515
+ }
502
516
  var _actualDeductAmount = Decimal.min(deductionLeft, _maxDeductForProduct);
503
517
 
504
518
  // 计算实际抵扣的数量
@@ -512,8 +526,7 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
512
526
  parent_product_id: targetProduct.parent_product_id || null,
513
527
  is_bundle_item: targetProduct.is_bundle_item || false,
514
528
  deductAmount: _actualDeductAmount.toNumber(),
515
- // 转换为数字
516
- deductQuantity: _actualDeductQty // 抵扣涉及的数量(用于记录)
529
+ deductQuantity: _actualDeductQty
517
530
  });
518
531
  }
519
532
  var totalDeducted = maxDeduction.minus(deductionLeft);
@@ -524,9 +537,9 @@ export function processVouchers(applicableVouchers, orderTotalAmount, products)
524
537
  // 更新券使用次数(按 product_id 统计)
525
538
  usedVoucherCounts.set(product_id, (usedVoucherCounts.get(product_id) || 0) + 1);
526
539
 
527
- // 更新 maxPassesPerItem 追踪:记录每个被抵扣的商品行
540
+ // 更新 maxPassesPerItem 追踪:按实际抵扣数量递增
528
541
  deductionDetails.forEach(function (detail) {
529
- incrementItemPassUsage(itemPassUsageMap, product_id, detail.product_id);
542
+ incrementItemPassUsage(itemPassUsageMap, product_id, detail.product_id, detail.deductQuantity);
530
543
  });
531
544
 
532
545
  // 添加到推荐列表(包含基于当前剩余金额计算的 available_max_amount)
@@ -618,16 +631,17 @@ export function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmo
618
631
  return ((_itemPassUsageMap$get = itemPassUsageMap.get(walletPassProductId)) === null || _itemPassUsageMap$get === void 0 ? void 0 : _itemPassUsageMap$get.get(orderItemProductId)) || 0;
619
632
  };
620
633
  var incrementItemPassUsage = function incrementItemPassUsage(walletPassProductId, orderItemProductId) {
634
+ var count = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
621
635
  if (!itemPassUsageMap.has(walletPassProductId)) {
622
636
  itemPassUsageMap.set(walletPassProductId, new Map());
623
637
  }
624
638
  var innerMap = itemPassUsageMap.get(walletPassProductId);
625
- innerMap.set(orderItemProductId, (innerMap.get(orderItemProductId) || 0) + 1);
639
+ innerMap.set(orderItemProductId, (innerMap.get(orderItemProductId) || 0) + count);
626
640
  };
627
641
  var filterByMaxPassesPerItem = function filterByMaxPassesPerItem(products, walletPassProductId, maxPassesPerItem) {
628
642
  if (maxPassesPerItem <= 0) return products; // 0 = 不限制
629
643
  return products.filter(function (p) {
630
- return getItemPassUsage(walletPassProductId, p.product_id) < maxPassesPerItem;
644
+ return getItemPassUsage(walletPassProductId, p.product_id) < maxPassesPerItem * getTotalQuantityByProductId(productsForCalc, p.product_id);
631
645
  });
632
646
  };
633
647
 
@@ -715,17 +729,16 @@ export function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmo
715
729
  _iterator4.f();
716
730
  }
717
731
  } else {
718
- // 非跨商品券:只抵扣一个商品(剩余金额最高的),也受 applicableProductLimit 限制
732
+ // 非跨商品券:选择单价最高的商品(优先抵扣高价商品)
719
733
  var targetProduct = applicableProducts.reduce(function (max, p) {
720
- return p[amountField].greaterThan(max[amountField]) ? p : max;
734
+ return p[unitPriceField].greaterThan(max[unitPriceField]) ? p : max;
721
735
  });
722
736
 
723
- // 动态计算当前可抵扣数量
724
- var _currentAvailableQty5 = Math.ceil(targetProduct[amountField].dividedBy(targetProduct[unitPriceField]).toNumber());
725
- var _availableQty2 = applicableProductLimit > 0 ? Math.min(_currentAvailableQty5, applicableProductLimit) : _currentAvailableQty5;
726
-
727
- // 计算本商品最大可抵扣金额 = min(数量 * 单价, 剩余金额)
728
- var _maxDeductForProduct2 = Decimal.min(targetProduct[unitPriceField].times(_availableQty2), targetProduct[amountField]);
737
+ // maxPassesPerItem 限制每张券最多抵扣的单位数
738
+ var _maxDeductForProduct2 = targetProduct[amountField];
739
+ if (maxPassesPerItem > 0) {
740
+ _maxDeductForProduct2 = Decimal.min(targetProduct[unitPriceField].times(maxPassesPerItem), targetProduct[amountField]);
741
+ }
729
742
  var _actualDeductAmount2 = Decimal.min(deductionLeft, _maxDeductForProduct2);
730
743
 
731
744
  // 计算实际抵扣的数量
@@ -739,8 +752,7 @@ export function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmo
739
752
  parent_product_id: targetProduct.parent_product_id || null,
740
753
  is_bundle_item: targetProduct.is_bundle_item || false,
741
754
  deductAmount: _actualDeductAmount2.toNumber(),
742
- // 转换为数字
743
- deductQuantity: _actualDeductQty2 // 抵扣涉及的数量(用于记录)
755
+ deductQuantity: _actualDeductQty2
744
756
  });
745
757
  }
746
758
  var totalDeducted = maxDeduction.minus(deductionLeft);
@@ -748,9 +760,9 @@ export function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmo
748
760
  // 更新订单剩余金额
749
761
  remainingOrderAmount = remainingOrderAmount.minus(totalDeducted);
750
762
 
751
- // 更新 maxPassesPerItem 追踪:记录每个被抵扣的商品行
763
+ // 更新 maxPassesPerItem 追踪:按实际抵扣数量递增
752
764
  deductionDetails.forEach(function (detail) {
753
- incrementItemPassUsage(selectedVoucher.product_id, detail.product_id);
765
+ incrementItemPassUsage(selectedVoucher.product_id, detail.product_id, detail.deductQuantity);
754
766
  });
755
767
  selectedWithDetails.push(_objectSpread(_objectSpread({}, selectedVoucher), {}, {
756
768
  actualDeduction: totalDeducted.toNumber(),
@@ -864,15 +876,16 @@ export function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmo
864
876
  }, new Decimal(0));
865
877
  }
866
878
  } else {
867
- // 非跨商品券:单个剩余金额最高的商品,也受 applicableProductLimit 限制
879
+ // 非跨商品券:选择单价最高的商品(优先抵扣高价商品)
868
880
  var maxProduct = applicableProducts.reduce(function (max, p) {
869
- return p[amountField].greaterThan(max[amountField]) ? p : max;
881
+ return p[unitPriceField].greaterThan(max[unitPriceField]) ? p : max;
870
882
  });
871
- // 动态计算当前可抵扣数量
872
- var _currentAvailableQty6 = Math.ceil(maxProduct[amountField].dividedBy(maxProduct[unitPriceField]).toNumber());
873
- var _deductQty3 = applicableProductLimit > 0 ? Math.min(_currentAvailableQty6, applicableProductLimit) : _currentAvailableQty6;
874
- // 实际可抵扣金额 = min(数量 * 单价, 剩余金额)
875
- calculatedMaxAmount = Decimal.min(maxProduct[unitPriceField].times(_deductQty3), 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
+ }
876
889
  }
877
890
  calculatedMaxAmount = Decimal.min(baseAmount, calculatedMaxAmount, remainingOrderAmount);
878
891
  if (calculatedMaxAmount.lessThanOrEqualTo(0)) {
@@ -311,7 +311,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
311
311
  date: string;
312
312
  status: string;
313
313
  week: string;
314
- weekNum: 0 | 1 | 2 | 3 | 4 | 5 | 6;
314
+ weekNum: 0 | 2 | 1 | 3 | 4 | 5 | 6;
315
315
  }[]>;
316
316
  submitTimeSlot(timeSlots: TimeSliceItem): void;
317
317
  private getScheduleDataByIds;
@@ -115,7 +115,7 @@ export declare class BookingTicketImpl extends BaseModule implements Module {
115
115
  * 获取当前的客户搜索条件
116
116
  * @returns 当前搜索条件
117
117
  */
118
- getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "num" | "skip">;
118
+ getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
119
119
  /**
120
120
  * 获取客户列表状态(包含滚动加载相关状态)
121
121
  * @returns 客户状态
@@ -41,7 +41,7 @@ export interface Voucher {
41
41
  allowCrossProduct: boolean;
42
42
  /** 可用商品数量上限 (仅多商品) 默认为0,表示不限制商品数量。 */
43
43
  applicableProductLimit: number;
44
- /** 单商品可用卡券上限(同一 Wallet Pass 商品生成的卡券对同一商品行最多抵扣次数)。默认为 0,表示不限制。 */
44
+ /** 单商品可用卡券上限(同一 Wallet Pass 商品生成的卡券对同一商品的每个 unit 最多抵扣次数,总上限 = maxPassesPerItem × quantity)。默认为 0,表示不限制。 */
45
45
  maxPassesPerItem: number;
46
46
  };
47
47
  }
@@ -129,7 +129,7 @@ export interface EvaluatorInput {
129
129
  allowCrossProduct: boolean;
130
130
  /** 可用商品数量上限 (仅多商品) 默认为0,表示不限制商品数量。 */
131
131
  applicableProductLimit: number;
132
- /** 单商品可用卡券上限(同一 Wallet Pass 商品生成的卡券对同一商品行最多抵扣次数)。默认为 0,表示不限制。 */
132
+ /** 单商品可用卡券上限(同一 Wallet Pass 商品生成的卡券对同一商品的每个 unit 最多抵扣次数,总上限 = maxPassesPerItem × quantity)。默认为 0,表示不限制。 */
133
133
  maxPassesPerItem: number;
134
134
  }>[];
135
135
  }
@@ -82,6 +82,9 @@ var getApplicableProducts = (voucher, productsData) => {
82
82
  }
83
83
  return productsData.filter((p) => applicableProductIds.includes(p.product_id));
84
84
  };
85
+ var getTotalQuantityByProductId = (allProducts, productId) => {
86
+ return allProducts.filter((p) => p.product_id === productId).reduce((sum, p) => sum + getProductQuantity(p), 0);
87
+ };
85
88
  function processVouchers(applicableVouchers, orderTotalAmount, products) {
86
89
  console.log(products, "products123");
87
90
  const productsCopy = expandProductsWithBundleItems(products, true);
@@ -90,18 +93,18 @@ function processVouchers(applicableVouchers, orderTotalAmount, products) {
90
93
  var _a;
91
94
  return ((_a = usageMap.get(walletPassProductId)) == null ? void 0 : _a.get(orderItemProductId)) || 0;
92
95
  };
93
- const incrementItemPassUsage = (usageMap, walletPassProductId, orderItemProductId) => {
96
+ const incrementItemPassUsage = (usageMap, walletPassProductId, orderItemProductId, count = 1) => {
94
97
  if (!usageMap.has(walletPassProductId)) {
95
98
  usageMap.set(walletPassProductId, /* @__PURE__ */ new Map());
96
99
  }
97
100
  const innerMap = usageMap.get(walletPassProductId);
98
- innerMap.set(orderItemProductId, (innerMap.get(orderItemProductId) || 0) + 1);
101
+ innerMap.set(orderItemProductId, (innerMap.get(orderItemProductId) || 0) + count);
99
102
  };
100
- const filterByMaxPassesPerItem = (products2, usageMap, walletPassProductId, maxPassesPerItem) => {
103
+ const filterByMaxPassesPerItem = (products2, allProducts, usageMap, walletPassProductId, maxPassesPerItem) => {
101
104
  if (maxPassesPerItem <= 0)
102
105
  return products2;
103
106
  return products2.filter(
104
- (p) => getItemPassUsage(usageMap, walletPassProductId, p.product_id) < maxPassesPerItem
107
+ (p) => getItemPassUsage(usageMap, walletPassProductId, p.product_id) < maxPassesPerItem * getTotalQuantityByProductId(allProducts, p.product_id)
105
108
  );
106
109
  };
107
110
  const calculateAvailableMaxAmount = (voucher, productsData, itemPassUsage) => {
@@ -116,7 +119,7 @@ function processVouchers(applicableVouchers, orderTotalAmount, products) {
116
119
  const amountField = deductTaxAndFee ? "remainingAmountWithTax" : "remainingAmountPure";
117
120
  let applicableProducts = getApplicableProducts(voucher, productsData).filter((p) => p[amountField].greaterThan(0));
118
121
  if (itemPassUsage) {
119
- applicableProducts = filterByMaxPassesPerItem(applicableProducts, itemPassUsage, voucher.product_id, maxPassesPerItem);
122
+ applicableProducts = filterByMaxPassesPerItem(applicableProducts, productsData, itemPassUsage, voucher.product_id, maxPassesPerItem);
120
123
  }
121
124
  if (applicableProducts.length === 0) {
122
125
  return new import_decimal.default(0);
@@ -146,14 +149,16 @@ function processVouchers(applicableVouchers, orderTotalAmount, products) {
146
149
  }
147
150
  } else {
148
151
  const maxProduct = applicableProducts.reduce(
149
- (max, p) => p[amountField].greaterThan(max[amountField]) ? p : max
150
- );
151
- const currentAvailableQty = Math.ceil(maxProduct[amountField].dividedBy(maxProduct[unitPriceField]).toNumber());
152
- const deductQty = applicableProductLimit > 0 ? Math.min(currentAvailableQty, applicableProductLimit) : currentAvailableQty;
153
- finalApplicableAmount = import_decimal.default.min(
154
- maxProduct[unitPriceField].times(deductQty),
155
- maxProduct[amountField]
152
+ (max, p) => p[unitPriceField].greaterThan(max[unitPriceField]) ? p : max
156
153
  );
154
+ if (maxPassesPerItem > 0) {
155
+ finalApplicableAmount = import_decimal.default.min(
156
+ maxProduct[unitPriceField].times(maxPassesPerItem),
157
+ maxProduct[amountField]
158
+ );
159
+ } else {
160
+ finalApplicableAmount = maxProduct[amountField];
161
+ }
157
162
  }
158
163
  return import_decimal.default.min(baseAmount, finalApplicableAmount, remainingOrderAmount);
159
164
  };
@@ -180,7 +185,7 @@ function processVouchers(applicableVouchers, orderTotalAmount, products) {
180
185
  if (maxPassesPerItem > 0 && itemPassUsage) {
181
186
  const deductTaxAndFee = (config == null ? void 0 : config.deductTaxAndFee) ?? true;
182
187
  const amountField = deductTaxAndFee ? "remainingAmountWithTax" : "remainingAmountPure";
183
- const availableAfterPassLimit = getApplicableProducts(voucher, productsData).filter((p) => p[amountField].greaterThan(0)).filter((p) => getItemPassUsage(itemPassUsage, product_id, p.product_id) < maxPassesPerItem);
188
+ 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));
184
189
  if (availableAfterPassLimit.length === 0) {
185
190
  return { isAvailable: false, reasonCode: "max_passes_per_item_reached" };
186
191
  }
@@ -230,7 +235,7 @@ function processVouchers(applicableVouchers, orderTotalAmount, products) {
230
235
  voucher,
231
236
  productsForRecommendation
232
237
  ).filter((p) => p[amountField].greaterThan(0));
233
- applicableProducts = filterByMaxPassesPerItem(applicableProducts, itemPassUsageMap, product_id, maxPassesPerItem);
238
+ applicableProducts = filterByMaxPassesPerItem(applicableProducts, productsForRecommendation, itemPassUsageMap, product_id, maxPassesPerItem);
234
239
  if (applicableProducts.length === 0)
235
240
  return false;
236
241
  const usageAmount = typeof voucher.edit_current_amount === "number" ? voucher.edit_current_amount : getRecommendedAmount(voucher);
@@ -263,14 +268,16 @@ function processVouchers(applicableVouchers, orderTotalAmount, products) {
263
268
  }
264
269
  } else {
265
270
  const maxProduct = applicableProducts.reduce(
266
- (max, p) => p[amountField].greaterThan(max[amountField]) ? p : max
267
- );
268
- const currentAvailableQty = Math.ceil(maxProduct[amountField].dividedBy(maxProduct[unitPriceField]).toNumber());
269
- const deductQty = applicableProductLimit > 0 ? Math.min(currentAvailableQty, applicableProductLimit) : currentAvailableQty;
270
- calculatedAvailableMaxAmount = import_decimal.default.min(
271
- maxProduct[unitPriceField].times(deductQty),
272
- maxProduct[amountField]
271
+ (max, p) => p[unitPriceField].greaterThan(max[unitPriceField]) ? p : max
273
272
  );
273
+ if (maxPassesPerItem > 0) {
274
+ calculatedAvailableMaxAmount = import_decimal.default.min(
275
+ maxProduct[unitPriceField].times(maxPassesPerItem),
276
+ maxProduct[amountField]
277
+ );
278
+ } else {
279
+ calculatedAvailableMaxAmount = maxProduct[amountField];
280
+ }
274
281
  }
275
282
  const availableMaxAmount = import_decimal.default.min(
276
283
  baseAmount,
@@ -314,14 +321,15 @@ function processVouchers(applicableVouchers, orderTotalAmount, products) {
314
321
  }
315
322
  } else {
316
323
  const targetProduct = applicableProducts.reduce(
317
- (max, p) => p[amountField].greaterThan(max[amountField]) ? p : max
318
- );
319
- const currentAvailableQty = Math.ceil(targetProduct[amountField].dividedBy(targetProduct[unitPriceField]).toNumber());
320
- const availableQty = applicableProductLimit > 0 ? Math.min(currentAvailableQty, applicableProductLimit) : currentAvailableQty;
321
- const maxDeductForProduct = import_decimal.default.min(
322
- targetProduct[unitPriceField].times(availableQty),
323
- targetProduct[amountField]
324
+ (max, p) => p[unitPriceField].greaterThan(max[unitPriceField]) ? p : max
324
325
  );
326
+ let maxDeductForProduct = targetProduct[amountField];
327
+ if (maxPassesPerItem > 0) {
328
+ maxDeductForProduct = import_decimal.default.min(
329
+ targetProduct[unitPriceField].times(maxPassesPerItem),
330
+ targetProduct[amountField]
331
+ );
332
+ }
325
333
  const actualDeductAmount = import_decimal.default.min(deductionLeft, maxDeductForProduct);
326
334
  const actualDeductQty = Math.ceil(actualDeductAmount.dividedBy(targetProduct[unitPriceField]).toNumber());
327
335
  targetProduct[amountField] = targetProduct[amountField].minus(actualDeductAmount);
@@ -331,9 +339,7 @@ function processVouchers(applicableVouchers, orderTotalAmount, products) {
331
339
  parent_product_id: targetProduct.parent_product_id || null,
332
340
  is_bundle_item: targetProduct.is_bundle_item || false,
333
341
  deductAmount: actualDeductAmount.toNumber(),
334
- // 转换为数字
335
342
  deductQuantity: actualDeductQty
336
- // 抵扣涉及的数量(用于记录)
337
343
  });
338
344
  }
339
345
  const totalDeducted = maxDeduction.minus(deductionLeft);
@@ -341,7 +347,7 @@ function processVouchers(applicableVouchers, orderTotalAmount, products) {
341
347
  remainingOrderAmount = remainingOrderAmount.minus(totalDeducted);
342
348
  usedVoucherCounts.set(product_id, (usedVoucherCounts.get(product_id) || 0) + 1);
343
349
  deductionDetails.forEach((detail) => {
344
- incrementItemPassUsage(itemPassUsageMap, product_id, detail.product_id);
350
+ incrementItemPassUsage(itemPassUsageMap, product_id, detail.product_id, detail.deductQuantity);
345
351
  });
346
352
  recommendedVouchers.push({
347
353
  ...voucher,
@@ -389,18 +395,18 @@ function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, pr
389
395
  var _a;
390
396
  return ((_a = itemPassUsageMap.get(walletPassProductId)) == null ? void 0 : _a.get(orderItemProductId)) || 0;
391
397
  };
392
- const incrementItemPassUsage = (walletPassProductId, orderItemProductId) => {
398
+ const incrementItemPassUsage = (walletPassProductId, orderItemProductId, count = 1) => {
393
399
  if (!itemPassUsageMap.has(walletPassProductId)) {
394
400
  itemPassUsageMap.set(walletPassProductId, /* @__PURE__ */ new Map());
395
401
  }
396
402
  const innerMap = itemPassUsageMap.get(walletPassProductId);
397
- innerMap.set(orderItemProductId, (innerMap.get(orderItemProductId) || 0) + 1);
403
+ innerMap.set(orderItemProductId, (innerMap.get(orderItemProductId) || 0) + count);
398
404
  };
399
405
  const filterByMaxPassesPerItem = (products2, walletPassProductId, maxPassesPerItem) => {
400
406
  if (maxPassesPerItem <= 0)
401
407
  return products2;
402
408
  return products2.filter(
403
- (p) => getItemPassUsage(walletPassProductId, p.product_id) < maxPassesPerItem
409
+ (p) => getItemPassUsage(walletPassProductId, p.product_id) < maxPassesPerItem * getTotalQuantityByProductId(productsForCalc, p.product_id)
404
410
  );
405
411
  };
406
412
  selectedVouchers.forEach((selectedVoucher) => {
@@ -463,14 +469,15 @@ function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, pr
463
469
  }
464
470
  } else {
465
471
  const targetProduct = applicableProducts.reduce(
466
- (max, p) => p[amountField].greaterThan(max[amountField]) ? p : max
467
- );
468
- const currentAvailableQty = Math.ceil(targetProduct[amountField].dividedBy(targetProduct[unitPriceField]).toNumber());
469
- const availableQty = applicableProductLimit > 0 ? Math.min(currentAvailableQty, applicableProductLimit) : currentAvailableQty;
470
- const maxDeductForProduct = import_decimal.default.min(
471
- targetProduct[unitPriceField].times(availableQty),
472
- targetProduct[amountField]
472
+ (max, p) => p[unitPriceField].greaterThan(max[unitPriceField]) ? p : max
473
473
  );
474
+ let maxDeductForProduct = targetProduct[amountField];
475
+ if (maxPassesPerItem > 0) {
476
+ maxDeductForProduct = import_decimal.default.min(
477
+ targetProduct[unitPriceField].times(maxPassesPerItem),
478
+ targetProduct[amountField]
479
+ );
480
+ }
474
481
  const actualDeductAmount = import_decimal.default.min(deductionLeft, maxDeductForProduct);
475
482
  const actualDeductQty = Math.ceil(actualDeductAmount.dividedBy(targetProduct[unitPriceField]).toNumber());
476
483
  targetProduct[amountField] = targetProduct[amountField].minus(actualDeductAmount);
@@ -480,15 +487,13 @@ function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, pr
480
487
  parent_product_id: targetProduct.parent_product_id || null,
481
488
  is_bundle_item: targetProduct.is_bundle_item || false,
482
489
  deductAmount: actualDeductAmount.toNumber(),
483
- // 转换为数字
484
490
  deductQuantity: actualDeductQty
485
- // 抵扣涉及的数量(用于记录)
486
491
  });
487
492
  }
488
493
  const totalDeducted = maxDeduction.minus(deductionLeft);
489
494
  remainingOrderAmount = remainingOrderAmount.minus(totalDeducted);
490
495
  deductionDetails.forEach((detail) => {
491
- incrementItemPassUsage(selectedVoucher.product_id, detail.product_id);
496
+ incrementItemPassUsage(selectedVoucher.product_id, detail.product_id, detail.deductQuantity);
492
497
  });
493
498
  selectedWithDetails.push({
494
499
  ...selectedVoucher,
@@ -572,14 +577,16 @@ function recalculateVouchers(allVouchers, selectedVouchers, orderTotalAmount, pr
572
577
  }
573
578
  } else {
574
579
  const maxProduct = applicableProducts.reduce(
575
- (max, p) => p[amountField].greaterThan(max[amountField]) ? p : max
576
- );
577
- const currentAvailableQty = Math.ceil(maxProduct[amountField].dividedBy(maxProduct[unitPriceField]).toNumber());
578
- const deductQty = applicableProductLimit > 0 ? Math.min(currentAvailableQty, applicableProductLimit) : currentAvailableQty;
579
- calculatedMaxAmount = import_decimal.default.min(
580
- maxProduct[unitPriceField].times(deductQty),
581
- maxProduct[amountField]
580
+ (max, p) => p[unitPriceField].greaterThan(max[unitPriceField]) ? p : max
582
581
  );
582
+ if (maxPassesPerItem > 0) {
583
+ calculatedMaxAmount = import_decimal.default.min(
584
+ maxProduct[unitPriceField].times(maxPassesPerItem),
585
+ maxProduct[amountField]
586
+ );
587
+ } else {
588
+ calculatedMaxAmount = maxProduct[amountField];
589
+ }
583
590
  }
584
591
  calculatedMaxAmount = import_decimal.default.min(
585
592
  baseAmount,
@@ -311,7 +311,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
311
311
  date: string;
312
312
  status: string;
313
313
  week: string;
314
- weekNum: 0 | 1 | 2 | 3 | 4 | 5 | 6;
314
+ weekNum: 0 | 2 | 1 | 3 | 4 | 5 | 6;
315
315
  }[]>;
316
316
  submitTimeSlot(timeSlots: TimeSliceItem): void;
317
317
  private getScheduleDataByIds;
@@ -115,7 +115,7 @@ export declare class BookingTicketImpl extends BaseModule implements Module {
115
115
  * 获取当前的客户搜索条件
116
116
  * @returns 当前搜索条件
117
117
  */
118
- getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "num" | "skip">;
118
+ getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
119
119
  /**
120
120
  * 获取客户列表状态(包含滚动加载相关状态)
121
121
  * @returns 客户状态
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "2.1.106",
4
+ "version": "2.1.107",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",