@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.
- package/dist/model/strategy/adapter/walletPass/type.d.ts +2 -2
- package/dist/model/strategy/adapter/walletPass/utils.js +70 -57
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/BookingTicket/index.d.ts +1 -1
- package/lib/model/strategy/adapter/walletPass/type.d.ts +2 -2
- package/lib/model/strategy/adapter/walletPass/utils.js +58 -51
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.d.ts +1 -1
- package/package.json +1 -1
|
@@ -41,7 +41,7 @@ export interface Voucher {
|
|
|
41
41
|
allowCrossProduct: boolean;
|
|
42
42
|
/** 可用商品数量上限 (仅多商品) 默认为0,表示不限制商品数量。 */
|
|
43
43
|
applicableProductLimit: number;
|
|
44
|
-
/** 单商品可用卡券上限(同一 Wallet Pass
|
|
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
|
|
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 商品对指定订单商品行的已用卡券次数
|
|
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) +
|
|
147
|
+
innerMap.set(orderItemProductId, (innerMap.get(orderItemProductId) || 0) + count);
|
|
135
148
|
};
|
|
136
149
|
|
|
137
150
|
// 按 maxPassesPerItem 过滤商品:排除已达到单商品可用卡券上限的商品
|
|
138
|
-
|
|
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[
|
|
236
|
+
return p[unitPriceField].greaterThan(max[unitPriceField]) ? p : max;
|
|
223
237
|
});
|
|
224
|
-
//
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
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
|
-
//
|
|
443
|
+
// 非跨商品券:选择单价最高的商品(优先抵扣高价商品)
|
|
430
444
|
var maxProduct = applicableProducts.reduce(function (max, p) {
|
|
431
|
-
return p[
|
|
445
|
+
return p[unitPriceField].greaterThan(max[unitPriceField]) ? p : max;
|
|
432
446
|
});
|
|
433
|
-
//
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
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
|
|
463
|
-
var availableQty = Math.min(
|
|
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
|
-
//
|
|
506
|
+
// 非跨商品券:选择单价最高的商品(优先抵扣高价商品)
|
|
492
507
|
var targetProduct = applicableProducts.reduce(function (max, p) {
|
|
493
|
-
return p[
|
|
508
|
+
return p[unitPriceField].greaterThan(max[unitPriceField]) ? p : max;
|
|
494
509
|
});
|
|
495
510
|
|
|
496
|
-
//
|
|
497
|
-
var
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
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) +
|
|
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
|
-
//
|
|
732
|
+
// 非跨商品券:选择单价最高的商品(优先抵扣高价商品)
|
|
719
733
|
var targetProduct = applicableProducts.reduce(function (max, p) {
|
|
720
|
-
return p[
|
|
734
|
+
return p[unitPriceField].greaterThan(max[unitPriceField]) ? p : max;
|
|
721
735
|
});
|
|
722
736
|
|
|
723
|
-
//
|
|
724
|
-
var
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
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
|
-
//
|
|
879
|
+
// 非跨商品券:选择单价最高的商品(优先抵扣高价商品)
|
|
868
880
|
var maxProduct = applicableProducts.reduce(function (max, p) {
|
|
869
|
-
return p[
|
|
881
|
+
return p[unitPriceField].greaterThan(max[unitPriceField]) ? p : max;
|
|
870
882
|
});
|
|
871
|
-
//
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
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 |
|
|
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, "
|
|
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
|
|
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
|
|
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) +
|
|
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[
|
|
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[
|
|
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[
|
|
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) +
|
|
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[
|
|
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[
|
|
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 |
|
|
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, "
|
|
118
|
+
getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
|
|
119
119
|
/**
|
|
120
120
|
* 获取客户列表状态(包含滚动加载相关状态)
|
|
121
121
|
* @returns 客户状态
|